From 3a48abcbdb7add4330d1550e56cb5a11bd8aee0a Mon Sep 17 00:00:00 2001 From: "Thomas M. Hermann" Date: Fri, 3 Apr 2009 23:59:24 -0500 Subject: [PATCH] Documentation for the floating point extensions. Updated the documentation to include the floating point predicates, assertions and diagnostic functions. Performed a trivial reformatting of the HTML for better readability in emacs. Also, added an xml tag so that the document will work in nxml-mode. It would have been preferable to use nXhtml-mode, but that only works with emacs 22 and RHEL only packages emacs 21. --- documentation/lisp-unit.css | 1 + documentation/lisp-unit.html | 1167 +++++++++++++++++++++++++++--------------- 2 files changed, 760 insertions(+), 408 deletions(-) rewrite documentation/lisp-unit.html (81%) diff --git a/documentation/lisp-unit.css b/documentation/lisp-unit.css index a4414ed..77695ec 100644 --- a/documentation/lisp-unit.css +++ b/documentation/lisp-unit.css @@ -1,6 +1,7 @@ body { background-color: white; margin-left: 10%; + margin-right: 10%; } p, blockquote, li, dd, dt, td, th { diff --git a/documentation/lisp-unit.html b/documentation/lisp-unit.html dissimilarity index 81% index 44b6be1..1b2321b 100644 --- a/documentation/lisp-unit.html +++ b/documentation/lisp-unit.html @@ -1,408 +1,759 @@ - - - - LISP-UNIT - - - - - -

lisp-unit is a Common Lisp library that supports -unit testing. It is an extension of the - -library written by Chris Riesbeck. There is a long history of testing -packages in Lisp, usually called "regression" testers. More recent -packages in Lisp and other languages have been inspired by JUnit for -Java. For more information on both unit testing and JUnit, visit www.junit.org.

- -

This page has two parts:

- - - - -

Overview

- -

The main goal for lisp-unit was to make it simple -to use. The advantages of lisp-unit are:

- - - -

How to Use lisp-unit

- -
    -
  1. Load (or compile and load) (asdf:operate 'asdf:load-op :lisp-unit).
  2. - -
  3. Evaluate (in-package :lisp-unit).
  4. - -
  5. Load a file of tests. See below for how to define tests.
  6. - -
  7. Run the tests with run-tests.
  8. -
- -

Any test failures will be printed, along with a summary of how many tests were -run, how many passed, and how many failed.

- -

You define a test with define-test:

- -
(define-test name exp1 exp2 ...)
- -

This defines a test called name. The expressions can be anything, -but typically most will be -assertion forms.

- -

Tests can be defined before the code they test, even if they're testing -macros. This is to support -test-first programming.

- -

After defining your tests and the code they test, run -the tests with

- -
(run-tests)
- -

This runs every test defined -in the current package. To run just certain specific tests, use

- -
(run-tests name1 name2 ...)
- -

e.g., (run-tests greater summit).

- - -

The following example

- - -

First, we define some tests.

- -
> (in-package :example)
-#<PACKAGE EXAMPLE>
-> (define-test test-my-max
-   (assert-equal 5 (my-max 2 5))
-   (assert-equal 5 (my-max 5 2))
-   (assert-equal 10 (my-max 10 10))
-   (assert-equal 0 (my-max -5 0))
-   )
-TEST-MY-MAX
-
- -

Following good test-first programming practice, we run these -tests before writing any code.

- -
> (run-tests test-my-max)
-    TEST-MY-MAX: Undefined function MY-MAX called with arguments (2 5).
-
- -

This shows that we need to do some work. So we define our -broken version of my-max.

- -
> (defun my-max (x y) x)  ;; deliberately wrong
-MY-MAX
- -

Now we run the tests again:

- -
> (run-tests my-max)
-MY-MAX: (MY-MAX 2 5) failed: Expected 5 but saw 2
-MY-MAX: (MY-MAX -5 0) failed: Expected 0 but saw -5
-MY-MAX: 2 assertions passed, 2 failed.
- -

This shows two failures. In both cases, the equality test -returned NIL. In the first case it was because -(my-max 2 5) returned 2 when 5 was expected, and -in the second case, it was because -(my-max -5 0) returned -5 when 0 was expected.

- - -

Assertion Forms

- -

The most commonly used assertion form is

- -
(assert-equal value form)
- -

This tallies a failure if form returns a value -not equal to value. Both -value and test are -evaluated in the local lexical environment. This means -that you can use local variables in tests. In particular, -you can write loops that run many tests at once:

- -
> (define-test my-sqrt
-  (dotimes (i 5)
-    (assert-equal i (my-sqrt (* i i)))))
-MY-SQRT
-
-> (defun my-sqrt (n) (/ n 2))   ;; wrong!!
-
-> (run-tests my-sqrt)
-MY-SQRT: (MY-SQRT (* I I)) failed: Expected 1 but saw 1/2
-MY-SQRT: (MY-SQRT (* I I)) failed: Expected 3 but saw 9/2
-MY-SQRT: (MY-SQRT (* I I)) failed: Expected 4 but saw 8
-MY-SQRT: 2 assertions passed, 3 failed.
- -

However, the above output doesn't tell us for which values of i -the code failed. Fortunately, you can fix this by -adding expressions at the end of the assert-equal. -These expression and their values will be printed on failure.

- -
> (define-test my-sqrt
-  (dotimes (i 5)
-    (assert-equal i (my-sqrt (* i i)) i)))  ;; added i at the end
-MY-SQRT
-> (run-tests my-sqrt)
-MY-SQRT: (MY-SQRT (* I I)) failed: Expected 1 but saw 1/2
-   I => 1
-MY-SQRT: (MY-SQRT (* I I)) failed: Expected 3 but saw 9/2
-   I => 3
-MY-SQRT: (MY-SQRT (* I I)) failed: Expected 4 but saw 8
-   I => 4
-MY-SQRT: 2 assertions passed, 3 failed.
- -

The next most useful assertion form is

- -
(assert-true test)
- -

This tallies a failure if test returns false. Again, -if you need to print out extra information, just add expressions -after test.

- -

There are also assertion forms to test -what code prints, what errors code returns, or what -a macro expands into. -A complete list of assertion forms is in -the reference section.

- -

Do not confuse assert-true -with Common Lisp's assert macro. assert -is used in code to guarantee that some condition is true. If it isn't, -the code halts. assert has options you can use -to let a user fix what's wrong and resume execution. A similar collision -of names exists in JUnit and Java.

- - -

How to Organize Tests with Packages

- -

Tests are grouped internally by the current package, -so that a set of tests can be defined for one package -of code without interfering with tests for other packages.

- -

If your code is being defined in cl-user, -which is common when learning Common Lisp, but not for -production-level code, then you should define your tests -in cl-user as well.

- -

If your code is being defined in its own package, -you should define your tests either in that same package, -or in another package for test code. The latter -approach has the advantage of making sure that your -tests have access to only the exported symbols of your -code package.

- -

For example, if you were defining a date package, -your date.lisp file would look like this:

- -
(defpackage :date
-  (:use :common-lisp)
-  (:export #:date->string #:string->date))
-  
-(in-package :date)
-
-(defun date->string (date) ...)
-(defun string->date (string) ...)
-
- -

Your date-tests.lisp file would look like this:

- -
(defpackage :date-tests
-  (:use :common-lisp :lisp-unit :date))
-
-(in-package :date-tests)
-
-(define-test date->string
-  (assert-true (string= ... (date->string ...)))
-  ...)
-...
-
- - -

You could then run all your date tests in -the test package:

- -
(in-package :date-tests)
-
-(run-tests)
-
- -

Alternately, you could run all your date tests from any package -with:

- -
(lisp-unit:run-all-tests :date-tests)
- - - -

Reference Section

- -

Here is a list of the functions and macros -exported by lisp-unit.

- - -

Functions for managing tests

- -
-
(define-test name exp1 exp2 ...)
- -
This macro defines a test called name with the expressions -specified, in the package specified by -the value of *package* -in effect when define-test is executed. -The expresssions are assembled into runnable code whenever -needed by run-tests. Hence you can define or -redefine macros without reloading tests using those macros. -
- -
(get-tests [package)
-
This function returns the names of all -the tests that have been defined for the package. If no package -is given, the value of *package* is used.
- -
(get-test-code name [package)
-
This function returns the body of the code stored for the test -name under package. If no package -is given, the value of *package* is used.
- -
(remove-tests names [package])
-
This function removes the tests named for the given package. -If no package -is given, the value of *package* is used.
- -
(remove-all-tests [package])
-
This function removes the tests for the given package. -If no package is given, it removes all tests for the current package. -If nil is given, it removes all tests for all packages.
- -
(run-all-tests package)
-
This macro runs all the tests defined in the specified package -and reports the results.
- -
(run-tests name1 name2 ...)
-
This macro runs the tests named and reports the results. -The package used is the value of *package* -in effect when the macro is expanded. If no names are given, -all tests for that package are run.
- -
(use-debugger [flag])
-
By default, errors that occur while running tests are simply -counted and ignored. You can change this behavior by calling use-debugger -with one of three possible flag values: t (the default) means -your Lisp's normal error handling routines will be invoked when -errors occur; :ask means you will be asked what to do -when an error occurs, and nil means errors are counted and -ignored, i.e., the standard behavior.
- -
- - -

Forms for assertions

- -

All of the assertion forms are macros. -They tally a failure if the associated predication -returns false. Assertions can be made about -return values, printed output, macro expansions, and even -expected errors. Assertion form arguments are evaluated -in the local lexical environment.

- -

All assertion forms -allow you to include additional expressions at the end of the form. These -expressions and their values will -be printed only when the test fails.

- -

Return values are unspecified for all assertion forms.

- -
- -
(assert-eq value form [form1 form2 ...])
-
(assert-eql value form [form1 form2 ...])
-
(assert-equal value form [form1 form2 ...])
-
(assert-equalp value form [form1 form2 ...])
-
(assert-equality predicate value form [form1 form2 ...])
-
These macros tally a failure if value is not equal to -the result returned by form, using the specified equality predicate. -
-In general, assert-equal -is used for most tests.
-Example use of assert-equality: -
(assert-equality #'set-equal '(a b c) (unique-atoms '((b c) a ((b a) c))))
-
- -
(assert-true test [form1 form2 ...])
-
(assert-false test [form1 form2 ...])
-
assert-true -tallies a failure if test returns false. -assert-false -tallies a failure if test returns true.
-
- -
(assert-prints "output" form [form1 form2 ...])
-
This macro tallies a failure if form does not print to standard output stream -output equal to the -given string, ignoring differences in beginning and ending newlines.
- -
(assert-expands expansion form [form1 form2 ...])
-
This macro tallies a failure if (macroexpand-1 form) -does not produce a value equal to expansion. -
- -
(assert-error condition-type form [form1 form2 ...])
-
This macro tallies a failure if form does not -signal an error that -is equal to or a subtype of condition-type. Use error -to refer to any kind of error. See -condition -types in the Common Lisp Hyperspec for other possible names. For example, - -
(assert-error 'arithmetic-error (foo 0))
- -would assert that foo -is supposed to signal an arithmetic error when passed zero.
-
- - - -

Utility predicates

- -

Several predicate functions are exported that are often useful in -writing tests with assert-equality.

- -
-
(logically-equal value1 value2)
-
This predicate returns true of the two values are either -both true, i.e., non-NIL, or both false.
- -
(set-equal list1 list2 [:test])
-
This predicate returns true the first list is a subset of the -second and vice versa. :test -can be used to specify an equality predicate. The default is eql.
- - -
- -
- -

Comments or suggestions?

- - - + + + + + + + + LISP-UNIT + + + + + + + +

+ lisp-unit is a Common Lisp library that supports + unit testing. It is an extension of the + + library written by Chris Riesbeck . There is a long history of + testing packages in Lisp, usually called "regression" testers. More + recent packages in Lisp and other languages have been inspired by + JUnit for Java. For more information on both unit testing and JUnit, + visit www.junit.org. +

+ +

This page has two parts:

+ + + + +

Overview

+ +

+ The main goal for lisp-unit was to make it simple + to use. The advantages of lisp-unit are: +

+ + + +

How to Use lisp-unit

+ +
    +
  1. Load (or compile and load) (asdf:operate 'asdf:load-op :lisp-unit).
  2. +
  3. Evaluate (in-package :lisp-unit).
  4. +
  5. Load a file of tests. See below for how to define tests.
  6. +
  7. Run the tests with run-tests.
  8. +
+ +

+ Any test failures will be printed, along with a summary of how many + tests were run, how many passed, and how many failed. +

+ +

You define a test with define-test:

+ +
(define-test name exp1 exp2 ...)
+ +

+ This defines a test called name. The expressions can be + anything, but typically most will be + assertion forms. +

+ +

+ Tests can be defined before the code they test, even if they're + testing macros. This is to support + + test-first programming. +

+ +

+ After defining your tests and the code they test, run the tests with +

+ +
(run-tests)
+ +

+ This runs every test defined in the current package. To run just + certain specific tests, use +

+ +
(run-tests name1 name2 ...)
+ +

e.g., (run-tests greater summit).

+ + +

The following example

+ + +

First, we define some tests.

+ +
+> (in-package :example)
+#<PACKAGE EXAMPLE>
+> (define-test test-my-max
+   (assert-equal 5 (my-max 2 5))
+   (assert-equal 5 (my-max 5 2))
+   (assert-equal 10 (my-max 10 10))
+   (assert-equal 0 (my-max -5 0)))
+TEST-MY-MAX
+
+ +

+ Following good test-first programming practice, we run these tests + before writing any code. +

+ +
+> (run-tests test-my-max)
+TEST-MY-MAX: Undefined function MY-MAX called with arguments (2 5).
+
+ +

+ This shows that we need to do some work. So we define our broken + version of my-max. +

+ +
+> (defun my-max (x y) x)  ;; deliberately wrong
+MY-MAX
+
+ +

Now we run the tests again:

+ +
+> (run-tests my-max)
+MY-MAX: (MY-MAX 2 5) failed: Expected 5 but saw 2
+MY-MAX: (MY-MAX -5 0) failed: Expected 0 but saw -5
+MY-MAX: 2 assertions passed, 2 failed.
+
+ +

+ This shows two failures. In both cases, the equality test returned + NIL. In the first case it was because (my-max 2 5) + returned 2 when 5 was expected, and in the second case, it was + because (my-max -5 0) returned -5 when 0 was expected. +

+ + +

Assertion Forms

+ +

The most commonly used assertion form is

+ +
(assert-equal value form)
+ +

+ This tallies a failure if form returns a value not + equal to value. Both value and + test are evaluated in the local lexical environment. This + means that you can use local variables in tests. In particular, you + can write loops that run many tests at once: +

+ +
+> (define-test my-sqrt
+  (dotimes (i 5)
+    (assert-equal i (my-sqrt (* i i)))))
+MY-SQRT
+
+> (defun my-sqrt (n) (/ n 2))   ;; wrong!!
+
+> (run-tests my-sqrt)
+MY-SQRT: (MY-SQRT (* I I)) failed: Expected 1 but saw 1/2
+MY-SQRT: (MY-SQRT (* I I)) failed: Expected 3 but saw 9/2
+MY-SQRT: (MY-SQRT (* I I)) failed: Expected 4 but saw 8
+MY-SQRT: 2 assertions passed, 3 failed.
+
+ +

+ However, the above output doesn't tell us for which values of + i the code failed. Fortunately, you can fix this by + adding expressions at the end of the assert-equal. + These expression and their values will be printed on failure. +

+ +
+> (define-test my-sqrt
+  (dotimes (i 5)
+    (assert-equal i (my-sqrt (* i i)) i)))  ;; added i at the end
+MY-SQRT
+> (run-tests my-sqrt)
+MY-SQRT: (MY-SQRT (* I I)) failed: Expected 1 but saw 1/2
+   I => 1
+MY-SQRT: (MY-SQRT (* I I)) failed: Expected 3 but saw 9/2
+   I => 3
+MY-SQRT: (MY-SQRT (* I I)) failed: Expected 4 but saw 8
+   I => 4
+MY-SQRT: 2 assertions passed, 3 failed.
+
+ +

The next most useful assertion form is

+ +
(assert-true test)
+ +

+ This tallies a failure if test returns false. Again, if you + need to print out extra information, just add expressions after + test. +

+ +

+ There are also assertion forms to test what code prints, what errors + code returns, or what a macro expands into. A complete list of + assertion forms is in the reference + section. +

+ +

+ Do not confuse assert-true with Common Lisp's + assert macro. assert is used in code to + guarantee that some condition is true. If it isn't, the code + halts. assert has options you can use to let a user fix + what's wrong and resume execution. A similar collision of names + exists in JUnit and Java. +

+ +

How to Organize Tests with Packages

+ +

+ Tests are grouped internally by the current package, so that a set + of tests can be defined for one package of code without interfering + with tests for other packages. +

+ +

+ If your code is being defined in cl-user, which is + common when learning Common Lisp, but not for production-level code, + then you should define your tests in cl-user as well. +

+ +

+ If your code is being defined in its own package, you should define + your tests either in that same package, or in another package for + test code. The latter approach has the advantage of making sure that + your tests have access to only the exported symbols of your code + package. +

+ +

+ For example, if you were defining a date package, your + date.lisp file would look like this: +

+ +
+(defpackage :date
+  (:use :common-lisp)
+  (:export #:date->string #:string->date))
+  
+(in-package :date)
+
+(defun date->string (date) ...)
+(defun string->date (string) ...)
+
+ +

Your date-tests.lisp file would look like this:

+ +
+(defpackage :date-tests
+  (:use :common-lisp :lisp-unit :date))
+
+(in-package :date-tests)
+
+(define-test date->string
+  (assert-true (string= ... (date->string ...)))
+  ...)
+...
+
+ +

You could then run all your date tests in the test package:

+ +
+(in-package :date-tests)
+
+(run-tests)
+
+ +

+ Alternately, you could run all your date tests from any package + with: +

+ +
(lisp-unit:run-all-tests :date-tests)
+ + +

Reference Section

+ +

+ Here is a list of the functions and macros exported by + lisp-unit. +

+ + +

Functions for managing tests

+ +
+
+ (define-test name exp1 exp2 ...) +
+
+ This macro defines a test called name with the + expressions specified, in the package specified by the value of + *package* in effect when define-test is + executed. The expresssions are assembled into runnable + code whenever needed by run-tests. Hence you can + define or redefine macros without reloading tests using those + macros. +
+ +
+ (get-tests [package) +
+
+ This function returns the names of all the tests that have been + defined for the package. If no package is given, the + value of *package* is used. +
+ +
+ (get-test-code name [package) +
+
+ This function returns the body of the code stored for the test + name under package. If no package is given, the + value of *package* is used. +
+ +
+ (remove-tests names [package]) +
+
+ This function removes the tests named for the given package. If no + package is given, the value of *package* is used. +
+ +
+ (remove-all-tests [package]) +
+
+ This function removes the tests for the given package. If no + package is given, it removes all tests for the current package. + If nil is given, it removes all tests for all + packages. +
+ +
+ (run-all-tests package) +
+
+ This macro runs all the tests defined in the specified package and + reports the results. +
+ +
+ (run-tests name1 name2 ...) +
+
+ This macro runs the tests named and reports the results. The + package used is the value of *package* in effect when + the macro is expanded. If no names are given, all tests for + that package are run. +
+ +
+ (use-debugger [flag]) +
+
+ By default, errors that occur while running tests are simply + counted and ignored. You can change this behavior by calling + use-debugger with one of three possible flag values: + t (the default) means your Lisp's normal error handling + routines will be invoked when errors occur; :ask means + you will be asked what to do when an error occurs, and + nil means errors are counted and ignored, i.e., the + standard behavior. +
+
+ + +

Forms for assertions

+ +

+ All of the assertion forms are macros. They tally a failure if the + associated predication returns false. Assertions can be made about + return values, printed output, macro expansions, and even expected + errors. Assertion form arguments are evaluated in the local lexical + environment. +

+ +

+ All assertion forms allow you to include additional expressions at + the end of the form. These expressions and their values will be + printed only when the test fails. +

+ +

Return values are unspecified for all assertion forms.

+ +
+
+ (assert-eq value form [form1 form2 ...]) +
+
+ (assert-eql value form [form1 form2 ...]) +
+
+ (assert-equal value form [form1 form2 ...]) +
+
+ (assert-equalp value form [form1 form2 ...]) +
+
+ (assert-equality predicate value form [form1 form2 ...]) +
+
+ These macros tally a failure if value is not equal to the + result returned by form, using the specified equality + predicate. In general, assert-equal is used for most + tests. Example use of assert-equality: +
+      (assert-equality #'set-equal '(a b c) (unique-atoms '((b c) a ((b a) c))))
+    
+
+ +
+ (assert-true test [form1 form2 ...]) +
+
+ (assert-false test [form1 form2 ...]) +
+
+ assert-true tallies a failure if test + returns false. assert-false tallies a failure if + test returns true. +
+ +
+ (assert-prints "output" form [form1 form2 ...]) +
+
+ This macro tallies a failure if form does not print to standard + output stream output equal to the given string, ignoring + differences in beginning and ending newlines. +
+ +
+ (assert-expands expansion form [form1 form2 ...]) +
+
+ This macro tallies a failure if (macroexpand-1 + form) does not produce a value equal to + expansion. +
+ +
+ (assert-error condition-type form [form1 form2 ...]) +
+
+ This macro tallies a failure if form does not signal an + error that is equal to or a subtype of + condition-type. Use error to refer to any + kind of error. See condition + types in the Common Lisp Hyperspec for other possible + names. For example, + +
(assert-error 'arithmetic-error (foo 0))
+ + would assert that foo is supposed to signal an + arithmetic error when passed zero. +
+
+ + +

Utility predicates

+ +

+ Several predicate functions are exported that are often useful in + writing tests with assert-equality. +

+ +
+
+ (logically-equal value1 value2) +
+
+ This predicate returns true of the two values are either both + true, i.e., non-NIL, or both false. +
+ +
+ (set-equal list1 list2 [:test]) +
+
+ This predicate returns true the first list is a subset of the + second and vice versa. :test can be used to specify + an equality predicate. The default is eql. +
+
+ +

Floating point predicates and tests

+ +

+ The original list unit has been extended with several floating point + predicate functions and tests. The predicates can be used with + assert-equality or the corresponding tests can be + directly applied. All of the floating point comparisons are + considered equal if the relative error between the values is less + than some epsilon. The internal default value of + epsilon is is twice the appropriate float epsilon + (i.e. 2*single-float-epsilon or + 2*double-float-epsilon). Epsilon can be controlled at a + lexical level using the package variable *epsilon*. If + *epsilon* is set to nil, the internal + epsilon values are used. This is the default value of + epsilon. +

+ +
+
+ (float-equal float1 float2 [epsilon]) +
+
+ (assert-float-equal value form + [form1 form2 ...]) +
+
+ Return true if the relative error between + float1 and float2 + is less than epsilon. The test tallies the failure if + value is not equal to the result returned from + form, using float-equal. +
+ +
+ (complex-equal complex1 complex2 [epsilon]) +
+
+ (assert-complex-equal value form + [form1 form2 ...]) +
+
+ Return true if the relative error between + Real(complex1), + Real(complex2) and + Imaginary(complex1), + Imaginary(complex2) are each less than + epsilon. The test tallies the failure if + value is not equal to the result returned from + form, using complex-equal. +
+
+ (number-equal number1 number2 [epsilon]) +
+ +
+ (assert-number-equal value form + [form1 form2 ...]) +
+
+ Return true if the error between number1 + and number2 is less than + epsilon for floating point numbers. If the numbers + are integers, return true if the numbers are equal. The test + tallies the failure if value is not equal to the + result returned from form, using + number-equal. +
+ +
+ (sigfig-equal float1 float2 [significant-figures]) +
+
+ (assert-sigfig-equal value form + [form1 form2 ...]) +
+
+ Return true if float1 and + float2 are equal to the specified + significant-figures. The default value of significant + figures is 4, set by the global variable + *significant-figures. The test tallies the failure + if value is not equal to the result returned from + form, using sigfig-equal. +
+ +
+ (array-equal array1 array2 [:test]) +
+
+ (assert-array-equal test value form + [form1 form2 ...]) +
+
+ Return true if each element of array1 and + array2 is equal according to + :test which defaults to number-equal. + The test tallies the failure if value is not equal to + the result returned from form, using + numerical-equal. In general, test must + be a function that accepts 2 arguments and returns true + or false. +
+ +
+ (numerical-equal result1 result2 [:test]) +
+
+ (assert-numerical-equal value form + [form1 form2 ...]) +
+
+ Return true if the numerical result1 is + equal to result2 as defined by + :test. The results can be numbers, sequences, nested + sequences and arrays. The test tallies the failure if + value is not equal to the result returned from + form, using numerical-equal. In general, + test must be a function that accepts 2 arguments and + returns true or false. +
+
+ + +

Floating point diagnostic functions

+ +

+ Failing a unit test is only half of the problem. The other half is + understanding why the test failed and what is required to fix + it. The default values of epsilon will only be applicable + in a few situations. In many situations, the acceptable value of + epsilon is dependent on the routine being examined. When + testing large sequences or arrays, it is not enough to know that + each element is not equal. It is usually necessary to know which + specific elements are not equal. The functions presented in this + section facilitate diagnosis test failures for floating point + numbers, sequences and arrays. For tests that compare the relative + error against epsilon, the value of epsilon can be controlled by + setting *epsilon*. Similarly, if + sigfig-equal is used as the test, the number of + significant figures can be set by setting + *significant-figures*. +

+ +
+
+ (float-error float1 float2) +
+
+ Return the relative error between float1 + and float2. +
+ +
+ (float-error-epsilon float1 float2 [epsilon]) +
+
+ Return the error expressed as a multiple of epsilon. + (relative error)/epsilon +
+ +
+ (complex-epsilon complex1 complex2) +
+
+ Return a complex value with each component equal to the relative + error between the components of complex1 + and complex2, respectively. +
+ +
+ (complex-error-epsilon complex1 complex2 [epsilon]) +
+
+ Return a complex value with each component equal to the the error + expressed as a multiple of epsilon. +

+ #C((real relative error)/epsilon (imaginary + relative error)/epsilon) +

+
+ +
+ (number-epsilon number1 number2) +
+
+ Return the error between number1 and + number2. For float and complex numbers, + the result is equivalent to float-equal and + complex-equal, respectively. If the numbers are + integers, the absolute difference between them is returned. +
+ +
+ (number-error-epsilon number1 number2 [epsilon]) +
+
+ Return the error expressed as amultiple of epsilon. For floating + point numbers, this is equivalent to + float-error-epsilon. Similarly, for complex numbers + this is equivalent to complex-error-epsilon. This + function is not applicable to integers. +
+ +
+ (sequence-error sequence1 sequence2 + [:test] [:error-function]) +
+
+ Return a nested list of the elements that are not equal according + :test with the associated index and error data + reported by :error-function. +

+ (index number1 number2 (error-function n1 n2)) +

+
+ +
+ (array-error array1 array2 + [:test] [:error-function]) +
+
+ Return a nested list of the elements that are not equal according + :test with the associated indices and error data + reported by :error-function. +

+ (indices number1 number2 (error-function n1 n2)) +

+
+ +
+ +
+ +

+ Comments or suggestions? +

+ + + -- 2.11.4.GIT