commit d439d61c828a5fbf242a800af3ccf2690b34153a Author: nobody Date: Mon May 28 15:01:00 2001 +0000 This commit was manufactured by cvs2svn to create tag 'Version_1_22_0'. [SVN r10239] diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..3e84d7c7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,96 @@ +* text=auto !eol svneol=native#text/plain +*.gitattributes text svneol=native#text/plain + +# Scriptish formats +*.bat text svneol=native#text/plain +*.bsh text svneol=native#text/x-beanshell +*.cgi text svneol=native#text/plain +*.cmd text svneol=native#text/plain +*.js text svneol=native#text/javascript +*.php text svneol=native#text/x-php +*.pl text svneol=native#text/x-perl +*.pm text svneol=native#text/x-perl +*.py text svneol=native#text/x-python +*.sh eol=lf svneol=LF#text/x-sh +configure eol=lf svneol=LF#text/x-sh + +# Image formats +*.bmp binary svneol=unset#image/bmp +*.gif binary svneol=unset#image/gif +*.ico binary svneol=unset#image/ico +*.jpeg binary svneol=unset#image/jpeg +*.jpg binary svneol=unset#image/jpeg +*.png binary svneol=unset#image/png +*.tif binary svneol=unset#image/tiff +*.tiff binary svneol=unset#image/tiff +*.svg text svneol=native#image/svg%2Bxml + +# Data formats +*.pdf binary svneol=unset#application/pdf +*.avi binary svneol=unset#video/avi +*.doc binary svneol=unset#application/msword +*.dsp text svneol=crlf#text/plain +*.dsw text svneol=crlf#text/plain +*.eps binary svneol=unset#application/postscript +*.gz binary svneol=unset#application/gzip +*.mov binary svneol=unset#video/quicktime +*.mp3 binary svneol=unset#audio/mpeg +*.ppt binary svneol=unset#application/vnd.ms-powerpoint +*.ps binary svneol=unset#application/postscript +*.psd binary svneol=unset#application/photoshop +*.rdf binary svneol=unset#text/rdf +*.rss text svneol=unset#text/xml +*.rtf binary svneol=unset#text/rtf +*.sln text svneol=native#text/plain +*.swf binary svneol=unset#application/x-shockwave-flash +*.tgz binary svneol=unset#application/gzip +*.vcproj text svneol=native#text/xml +*.vcxproj text svneol=native#text/xml +*.vsprops text svneol=native#text/xml +*.wav binary svneol=unset#audio/wav +*.xls binary svneol=unset#application/vnd.ms-excel +*.zip binary svneol=unset#application/zip + +# Text formats +.htaccess text svneol=native#text/plain +*.bbk text svneol=native#text/xml +*.cmake text svneol=native#text/plain +*.css text svneol=native#text/css +*.dtd text svneol=native#text/xml +*.htm text svneol=native#text/html +*.html text svneol=native#text/html +*.ini text svneol=native#text/plain +*.log text svneol=native#text/plain +*.mak text svneol=native#text/plain +*.qbk text svneol=native#text/plain +*.rst text svneol=native#text/plain +*.sql text svneol=native#text/x-sql +*.txt text svneol=native#text/plain +*.xhtml text svneol=native#text/xhtml%2Bxml +*.xml text svneol=native#text/xml +*.xsd text svneol=native#text/xml +*.xsl text svneol=native#text/xml +*.xslt text svneol=native#text/xml +*.xul text svneol=native#text/xul +*.yml text svneol=native#text/plain +boost-no-inspect text svneol=native#text/plain +CHANGES text svneol=native#text/plain +COPYING text svneol=native#text/plain +INSTALL text svneol=native#text/plain +Jamfile text svneol=native#text/plain +Jamroot text svneol=native#text/plain +Jamfile.v2 text svneol=native#text/plain +Jamrules text svneol=native#text/plain +Makefile* text svneol=native#text/plain +README text svneol=native#text/plain +TODO text svneol=native#text/plain + +# Code formats +*.c text svneol=native#text/plain +*.cpp text svneol=native#text/plain +*.h text svneol=native#text/plain +*.hpp text svneol=native#text/plain +*.ipp text svneol=native#text/plain +*.tpp text svneol=native#text/plain +*.jam text svneol=native#text/plain +*.java text svneol=native#text/plain diff --git a/README b/README new file mode 100644 index 00000000..7328bbfa --- /dev/null +++ b/README @@ -0,0 +1,3 @@ +This is the main directory for the Boost Test Library. + +(Not to be confused with a directory containing test programs for the parent directory.) diff --git a/doc/execution_tools.htm b/doc/execution_tools.htm new file mode 100644 index 00000000..c6587b6c --- /dev/null +++ b/doc/execution_tools.htm @@ -0,0 +1,149 @@ + + + + + + + +Program Execution Library + + + + +

Boost +Test Library: Execution Tools

+

Introduction
+Benefits
+Specifications
+Sample Program
+Header Implementation Option
+Header boost/detail/catch_exceptions.hpp
+Rationale
+Design
+
+
Also see: Test Tools

+

Introduction

+

The Boost Test Library's Execution Tools provides a replacement main() +function which calls a user-supplied cpp_main() function within a try +block.. The library +supplied main() then catches and reports exceptions, relieving users from messy error detection and reporting +duties.

+

For use with the Execution Tools, the traditional Hello World +program becomes:

+
+
#include <iostream>
+
+int cpp_main( int, char *[] )  // note name
+{
+  std::cout << "Hello, world\n";
+  return 0;
+}
+
+

It really is that simple - just change the name of your initial function from +main to cpp_main.  Do make sure the argc and arcv parameters are specified +(although you don't have to name them if you don't use them).

+

When the above program executes, the output will be:

+
+
Hello, world
+no errors detected
+
+

But what if some lower-level function had thrown a runtime_error with the +message "big trouble"?  Then the output would look something like +this:

+
+
** exception: std::runtime_error: big trouble
+
**** returning with error code 200
+**********  errors detected; see stdout for details  ***********
+
+

And if a lower-level function had bubbled up a return code of 5, the output +would look something like this:

+
+
**** returning with error code 5
+**********  errors detected; see stdout for details  ***********
+
+

Note that the primary messages appear on stdout, while the final message +appears on stderr.  This increases the visibility of error notification if +stdout and stderr are directed to different devices or files.

+

Benefits

+

More uniform reporting of errors, particularly exceptions.

+

In production programs: 

+

More uniform error reporting is particularly useful for programs running +unattended under control of scripts or batch files. Some operating systems pop +up message boxes if an uncaught exception occurs, and this requires operator +intervention. By converting such exceptions to non-zero program return codes, +the library makes the program a better citizen.

+

More uniform reporting of errors isn't a benefit to some programs, +particularly programs always run by hand by a knowledgeable person. So cpp_main() +wouldn't be worth using in that environment.

+

In test programs:

+

More uniform error reporting is useful in test environments such as the boost +regression tests. See the Test Tools, +which uses cpp_main() as part of the test framework.

+

Specifications of the supplied main()

+

Uniformly detects and reports the occurrence of several types of errors, +reducing the various errors to a uniform return value which is returned to the +host environment.

+

There are two intended uses:

+ +

Requires: A user-supplied cpp_main() function with same interface as main().

+

Effects:

+
+

Call cpp_main( argc, argv ) in a try block.

+

Treat as errors:

+ +

Report errors to both cout (with details) and cerr (summary). Rationale: + Detail error reporting goes to cout so that it is properly interlaced with + other output, thus aiding error analysis. Summary goes to cerr in case cout is + redirected.

+
+

Returns: non-zero if any error was detected.

+

Sample Program

+
+
cpp_main_example.cpp
+
+

Header Implementation Option

+

The library supplied main() function may be stored in an object library and +linked into the final program just like any other supplied function.  If +this is not convenient, the main() function may be supplied at compile time by +including it as a header:

+
+
#include <boost/test/cpp_main.cpp>
+
+

Although this usage is unusual, it is quite useful in environments +where it may be difficult or undesirable to link to an object library.

+

Header boost/detail/catch_exceptions.hpp

+

The actual exception catching code from the replacement main() function has +been factored out into a separate header for those wishing to reuse this +code.  It is not otherwise documented.

+

Rationale

+

The components of a C++ program may report user-detected errors in several +ways, such as via a return value or throwing an exception.  System-detected +errors such as dereferencing an invalid pointer are reported in other ways, +totally operating system and compiler dependent. 

+

Yet many C++ programs, both production and test, must run in an environment +where uniform reporting of errors is necessary.  For example, converting +otherwise uncaught exceptions to non-zero program return codes allows many +command line, script, or batch environments to continue processing in a +controlled manner.  Even some GUI environments benefit from the unification +of errors into program return codes.

+

Design

+

The Boost Test Library Design +document describes the relationship between the Execution Tools and several +other components.

+
+

© Beman Dawes 2001

+

Revised: 28 February, 2001 +

+ + + + diff --git a/doc/index.htm b/doc/index.htm new file mode 100644 index 00000000..863717db --- /dev/null +++ b/doc/index.htm @@ -0,0 +1,104 @@ + + + + + + + +Boost Test Libraries + + + + + + + + + + + + + +
c++boost.gif (8819 bytes)Home Libraries People FAQ More
+ +

Boost Test +Library

+

Introduction
+Components
+
     Execution Tools
+     Test Tools
+Design
+Open Issues
+Portability
+Acknowledgements

+

Introduction

+

A matched set of tools for writing test programs, and controlling their +runtime execution.

+

The execution tools are also useful in some production (non-test) +environments.

+

Near zero dependencies between the tools allow mix-and-match tool +combinations without paying for features not used.

+

Components

+ + + +

Design

+See Boost Test Library Design.  +

Open Issues

+ + + + + +

Portability

+

Because the Boost Test Library is critical for porting and testing Boost libraries, it has been written to be very conservative in +its use of C++ features, and to keep dependencies to a bare minimum..

+

Tests have been run (and work) under numerous compilers.

+

Acknowledgements

+

Ed Brey, Kevlin Henney, Ullrich Koethe, and Thomas Matelich provided very +helpful comments during development. Dave Abrahams, Ed Brey, William Kempf, Jens +Maurer, and Wilka suggested numerous improvements during the Formal +Review.  Jens Maurer was the review manager.  Beman Dawes is the +developer and maintainer.

+
+

© Beman Dawes 2001

+

Revised 28 February, 2001 +

+ + + + diff --git a/doc/test_lib_design.htm b/doc/test_lib_design.htm new file mode 100644 index 00000000..4b16eb9e --- /dev/null +++ b/doc/test_lib_design.htm @@ -0,0 +1,190 @@ + + + + + + + +Program Execution, Test, and Unit Test Design Considerations + + + + +

Boost Test Library Design

+ +

Definitions
+Requirements
+Experience
+Layered Design
+Factored Design
+User-supplied Components
+Usage Patterns
+Paths Not Taken

+

Definitions

+

Execution Tools - Reports general errors +from lower-level components, and unifies various general error notifications +(return codes, exceptions, etc.) into the form appropriate for the host +operating environment. Intended for use with both production and test programs.

+

Test Tools - Execution Tools features, +plus reports test errors from lower-level components, and unifies various test +error notifications (test library specific return codes, exceptions, etc.) into +the form appropriate for the caller.  Functions or macros easing test case +construction.  Intended for use primarily in test programs.

+

Unit Test Tools - Provides a framework which facilitates the testing +of C++ classes, and the organization of these tests into test-suites. Intended +for use almost exclusively in test programs.

+

Requirements

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RequirementExecution
+ Tools
Test
+ Tools
Unit Test
+ Tools
Report errors from lower-level components.requiredrequiredrequired
Unify error notifications (return codes, exceptions, etc.) into a form + appropriate for the host operating environment.requiredrequiredrequired
Virtually no changes required in existing user programs.  Renaming main() allowed, but + that's about it.  (Note that changing existing programs may be desirable + to take advantage of certain features. The point of this requirement is + that you don't have to if you don't want to.)requiredrequirednot required; most programs using unit test tools will be written from + scratch to do so.
Virtually no perceived coupling or dependency costs.requiredrequiredsome cost acceptable
Maximum time required for an intermediate programmer to learn enough to + successfully use the tool.10 seconds plus however long it takes to convince themselves renaming + main() is really all they have to do.5-10 minutes30-60 minutes 
Functions or macros available to ease test case construction.not required or even desirablerequiredrequired
Classes, functions or macros to ease test suite construction.not required or even desirablenot required or even desirablerequired
+

Experience

+

Because the requirements for the other tools are almost a subset of the +Unit Test Tools requirements, it is tempting to supply only the Unit Test Tools, perhaps with some convenience functions to ease use for simple test or +execution error-detection.  Likewise, since Test Tools supplies the +functionality of Execution Tools, the Test Tools could be used Execution Toos.

+

Both unified approaches have been rejected, however, because of past negative +experience:

+ + +

Layered Design

+

The Main concept is equivalent to the specifications for a C++ main() +function as defined by the ISO C++ Standard.

+

The Execution Tools provides a non-recursive +program startup function which calls a user-supplied cpp_main() function +which meets the Main concept requirements. The supplied default implementation +for standard C++ environments uses main() for startup.  A GUI +implementation might supply a different start-up function, such as WinMain(), +but all implementations require the user supply a cpp_main() +function.  Note that the cpp_main() function may be supplied by the Test +Tools or by a user written program.

+

The startup function (that is, the replacement main()) shall meet its notification and +unification requirements above, including handling of all standard library +exceptions, char * and string exceptions, and if possible, signals from the +operating system or the hardware.

+

The Test Tools provide a cpp_main() function which calls a +user-supplied test_main() function, both of which meet the Main concept +requirements. Note that the test_main() function may be supplied by the Unit +Test Tools or by a user written program.

+

The Test Tools also provide a (independent, no other header +dependencies) header containing convenience macros and function +declarations.

+

The cpp_main() function for Test Tools shall meet its notification +and unification requirements above.  The Test Tools implementation +supplies the definitions for the functions supplied by the test_tools header.

+

Unit Test Tools shall provide a test_main() function which +meets the Main concept requirements.

+

A layered design is chosen as meeting all the requirements, being very +flexible and easy to implement, eliminating coupling and dependencies between +the libraries, allowing swapping of implementations, and allowing unit test +libraries to be developed at a later date.

+

The  Execution Tools and Test Tools both offer an unusual choice of allowing the user to choose either a +compile-time implementation by treating the implementation files as headers, or +a link-time implementation by treating the same implementation files as +separately compiled library source files.  (This portion of the design was contributed by +Ed Brey.)

+

Factored Design

+

The code which catches exceptions has been factored out (see boost/detail/catch_exceptions.hpp).  +This is done to facilitate reuse - this capability may be useful in other test +libraries or frameworks.  

+

User-supplied Components

+

In addition to being concrete implementations, the libraries act as a set of +specifications for their components.  User-supplied components which meet +those specifications may replace the library supplied components.

+

Usage Patterns

+

The expected usage patterns include:

+ +

Paths Not Taken

+

The Main concept is the one used by the C++ Standard, as inherited from the C +language.  More modern approaches were considered, including a generic +programming design parameterized on a function object type, and an object-oriented +design based on a common execution object.  Both were rejected as maximal +solutions to a minimal need, and as not meeting the "virtually no change in +user programs" requirement.

+

In the case of needing to make additional GUI arguments to startup functions +available, the requirement that startup function be non-recursive was +added.  This makes it simple and safe for the startup function source file +to store such arguments in its unnamed namespace, and supply an operating system +dependent function in the same source file to access those arguments.

+
+

© Beman Dawes 2001

+

Revised: 09 March, 2001 +

+ + + + diff --git a/doc/test_tools.htm b/doc/test_tools.htm new file mode 100644 index 00000000..9df48457 --- /dev/null +++ b/doc/test_tools.htm @@ -0,0 +1,159 @@ + + + + + + + +Test Tools Library + + + + +

Boost +Test Library: Test Tools

+

Introduction
+Example
+Test/Sample Programs
+Header Implementation Option
+Rationale
+Design
+
+
Also see: Execution Tools

+

Introduction

+

The Boost Test Library's Test Tools supply several components to ease creation and maintenance of +test programs.

+ + +

Boost Test Tools are intended for fairly simple test programs.  Execution Tools may be more suitable for production (non-test) programs.  +Unit Test +Tools may be more suitable for complex test +programs. 

+

The boost/test_tools.hpp macros and functions are intended for +test code rather than library or applications code, where throwing exceptions,  +assert(),  or BOOST_STATIC_ASSERT() may be more suitable ways to +detect and report errors.

+

Example

+

The example program shows four different ways to detect and report an error in the +add() function.

+
+
#include <boost/test/test_tools.hpp>    // see "Header Implementation Option"
+
+int add( int i, int j ) { return i+j; }
+
+int test_main( int, char *[] )  // note the name!
+{
+  // six ways to detect and report the same error:
+  BOOST_TEST( add(2,2) == 4 );           // #1 continues on error
+  BOOST_CRITICAL_TEST( add(2,2) == 4 );  // #2 throws on error
+  if ( add(2,2) != 4 )
+    BOOST_ERROR( "Ouch...");             // #3 continues on error
+  if ( add(2,2) != 4 )
+    BOOST_CRITICAL_ERROR("Ouch...");     // #4 throws on error
+  if ( add(2,2) != 4 ) throw "Oops...";  // #5 throws on error
+  return add(2,2) == 4 ? 0 : 1;          // #6 returns error code
+}
+
+

Approach #1 uses the BOOST_TEST macro, which displays an error message +on std::cout that includes the expression that failed, the source file name, and +the source file line number.  It also increments an error count.  At program termination, +the error count will be displayed automatically by the Boost Test Tools supplied cpp_main() function..

+

Approach #2 using the BOOST_CRITICAL_TEST macro, is similar to #1, except that after +displaying the error, an exception is thrown, to be caught by the library +supplied cpp_main() +function. This approach is suitable when writing a +explicit test program, and the error would be so severe as to make further +testing impractical. BOOST_CRITICAL_TEST differs from the C++ Standard Library's +assert() macro in that it is always generated, and channels error detection into +the uniform boost/test/test_main.cpp reporting procedure.

+

Approaches #3 and #4 are similar to #1 and #2 respectively, except +that the error detection is coded separately.  This is most useful when the +specific condition being tested is not indicative of the reason for failure.

+

Approach #5 throws an exception, which will be caught and reported by the +main() function supplied by either the Execution Tools or Test Tools.  This approach is suitable for both production and test code, in +libraries or not.  The error message displayed when the exception is caught +will be most meaningful if the exception is derived from std::exception, or is a +char * or std::string.

+

Approach #6 uses a return value to inform the caller of the error. This approach is particularly suitable for +integrating existing test code with the test tools library.  Although it +works fine with the Boost Program Execution or Test libraries, and is very +useful for running existing code under them, most C++ experts prefer using +exceptions for error reporting.

+

Test/Sample and Test Programs

+
+
test_tools_example.cpp
+test_tools_fail1.cpp
+test_tools_fail2.cpp
+test_tools_fail3.cpp
+test_tools_fail4.cpp
+
+

Header Implementation Option

+

The Boost Execution Tools main() function and Boost Test Tools supplied + cpp_main() functions may be stored in an object library +and linked into the final program just like any other supplied function.  +If this is not convenient, they can be compiled directly into the user's program +by defining a macro:

+
+
#define BOOST_INCLUDE_MAIN
+#include <boost/test/test_tools.hpp>
+
+

Although this usage is unusual, it is quite useful in some test environments +where it may be difficult or undesirable to link to an object library.

+

Rationale

+

How should a test program report errors?

+

Displaying an error message is an obvious possibility:

+
+
if ( something_bad_detected )
+  std::cout << "something bad has been detected" << std::endl;
+
+

But that requires inspection of the program's output after each run to +determine if an error occurred.  Since test programs are often run as part +of a regression test suite, human inspection of output to detect error messages +is too time consuming and unreliable. Test frameworks like GNU/expect can do the +inspections automatically, but are overly complex for simple testing.

+

A better simple way to report errors is for the test program to return +EXIT_SUCCESS (normally 0) if the test program completes satisfactorily, and +EXIT_FAILURE +if an error is detected.  This allows a simple regression test script to +automatically and unambiguous detect success or failure.  Further +appropriate actions such as creating an HTML table or emailing an alert can be +taken by the script, and can be modified as desired without having to change the +actual C++ test programs.

+

A testing protocol based on a policy of test programs returning EXIT_SUCCESS or +EXIT_FAILURE does not require any supporting tools; the C++ language and standard +library are sufficient.  The programmer must remember, however, to catch +all exceptions and convert them to program exits with non-zero return codes. The +programmer must also remember to not use the standard library assert() macro for +test code, because on some systems it results in undesirable side effects like a message +requiring manual intervention.

+

The Test Library automates those tasks, yet can be ignored by +programmers who prefer to implement the zero return testing protocol themselves.

+

Design

+

The Boost Test Library Design +document describes the relationship between the Boost Test Library components.

+
+

© Copyright Beman Dawes  2000

+ +

Revised 28 Feb 2001 +

+ + + + diff --git a/example/cpp_main_example.cpp b/example/cpp_main_example.cpp new file mode 100644 index 00000000..3f791668 --- /dev/null +++ b/example/cpp_main_example.cpp @@ -0,0 +1,12 @@ +// boost cpp_main_example program ------------------------------------------// + +#include // included rather than linked implementation + +int add( int i, int j ) { return i+j; } + +int cpp_main( int, char *[] ) // note the name! +{ + // two ways to detect and report the same error: + if ( add(2,2) != 4 ) throw "Oops..."; // #1 throws on error + return add(2,2) == 4 ? 0 : 1; // #2 returns error directly +} \ No newline at end of file diff --git a/example/test_tools_example.cpp b/example/test_tools_example.cpp new file mode 100644 index 00000000..bb9fc5f1 --- /dev/null +++ b/example/test_tools_example.cpp @@ -0,0 +1,19 @@ +// boost test_main example program ----------------------------------------// + +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include + +int add( int i, int j ) { return i+j; } + +int test_main( int, char *[] ) // note the name! +{ + // six ways to detect and report the same error: + BOOST_TEST( add(2,2) == 4 ); // #1 continues on error + BOOST_CRITICAL_TEST( add(2,2) == 4 ); // #2 throws on error + if ( add(2,2) != 4 ) + BOOST_ERROR( "Ouch..."); // #3 continues on error + if ( add(2,2) != 4 ) + BOOST_CRITICAL_ERROR( "Ouch..." ); // #4 throws on error + if ( add(2,2) != 4 ) throw "Oops..."; // #5 throws on error + return add(2,2) == 4 ? 0 : 1; // #6 returns error code +} diff --git a/include/boost/test/cpp_main.cpp b/include/boost/test/cpp_main.cpp new file mode 100644 index 00000000..fa19b70a --- /dev/null +++ b/include/boost/test/cpp_main.cpp @@ -0,0 +1,84 @@ +// boost/cpp_main.cpp (header or not, as you like it) ----------------------// + +// (C) Copyright Beman Dawes 1995-2001. Permission to copy, use, modify, sell +// and distribute this software is granted provided this copyright notice +// appears in all copies. This software is provided "as is" without express or +// implied warranty, and with no claim as to its suitability for any purpose. + +// See http://www.boost.org for updates, documentation, and revision history. + +// This file may be included as a header file, or may be compiled and placed +// in a library for traditional linking. It is unusual for non-template +// non-inline implementation code to be used as a header file, but the user +// may elect to do so because header-only implementation requires no library +// build support. (Suggested by Ed Brey) + +// Revision History +// 26 Feb 01 Numerous changes suggested during formal review. (Beman) +// 25 Jan 01 catch_exceptions.hpp code factored out. +// 22 Jan 01 Remove test_tools dependencies to reduce coupling. +// 5 Nov 00 Initial boost version (Beman Dawes) + +// header dependencies are deliberately restricted to reduce coupling. +#include +#include + +// main() ------------------------------------------------------------------// + +// Uniformly detects and reports the occurrence of several types of errors, +// reducing the various errors to a uniform return value which is returned +// to the host environment. +// +// There are two intended uses: +// +// * In production programs, which require no further action beyond +// naming the top-level function cpp_main() instead of main(). +// +// * In test frameworks, which supply cpp_main() to detect (or catch) +// test specific errors, report them, and then return a presumably +// non-zero value. +// +// Requires: A user-supplied cpp_main() function with same interface as main(). +// +// Effects: +// +// Call cpp_main( argc, argv ) in a try block. +// +// Treat as errors: +// +// * exceptions from cpp_main(). +// * non-zero return from cpp_main(). +// +// Report errors to both cout (with details) and cerr (summary). +// Rationale: Detail error reporting goes to cout so that it is properly +// interlaced with other output, thus aiding error analysis. Summary goes +// to cerr in case cout is redirected. +// +// Returns: non-zero if any error was detected. +// +// Note: this header is designed to work well if boost test tools happen to be +// used, but there is no requirement that they be used. There are no +// dependencies on test_tools headers. + +int cpp_main( int argc, char * argv[] ); // prototype for user's cpp_main() + +namespace boost +{ + namespace test + { + class cpp_main_caller + { + int argc; + char ** argv; + public: + cpp_main_caller( int c, char ** v ) : argc(c), argv(v) {} + int operator()() { return cpp_main( argc, argv ); } + }; + } +} + +int main( int argc, char * argv[] ) +{ + return boost::catch_exceptions( boost::test::cpp_main_caller(argc, argv), + std::cout, std::cerr ); +} diff --git a/include/boost/test/test_main.cpp b/include/boost/test/test_main.cpp new file mode 100644 index 00000000..36dc91a6 --- /dev/null +++ b/include/boost/test/test_main.cpp @@ -0,0 +1,87 @@ +// boost/test_main.cpp (header or not, as you like it) ----------------------// + +// (C) Copyright Beman Dawes 1995-2001. Permission to copy, use, modify, sell +// and distribute this software is granted provided this copyright notice +// appears in all copies. This software is provided "as is" without express or +// implied warranty, and with no claim as to its suitability for any purpose. + +// See http://www.boost.org for updates, documentation, and revision history. + +// This file may be included as a header file, or may be compiled and placed +// in a library for traditional linking. It is unusual for non-template +// non-inline implementation code to be used as a header file, but the user +// may elect to do so because header-only implementation requires no library +// build support. (Suggested by Ed Brey) + +// Revision History +// 26 Feb 01 Numerous changes suggested during formal review. (Beman) +// 22 Jan 01 Use boost/cpp_main.hpp as framework. (Beman) +// 5 Nov 00 Initial boost version (Beman Dawes) + +// header dependencies are deliberately kept minimal to reducing coupling. +#include // for exit codes +#include +#include + +namespace boost +{ + namespace test + { + int test_tools_errors = 0; // count of errors detected + + class test_tools_exception : public std::runtime_error + { + public: + test_tools_exception() : std::runtime_error("fatal test error") {}; + }; + } + + void report_error( const char * msg, const char * file, int line ) + { + ++test::test_tools_errors; + std::cout << "\n**** test failed: " << msg << ", file: " << file + << ", line: " << line << std::endl; + } + + void report_critical_error( const char * msg, const char * file, int line ) + { + report_error( msg, file, line ); + throw test::test_tools_exception(); + } +} + +// cpp_main() --------------------------------------------------------------// + +// See the boost/cpp_main.cpp comments; they apply to cpp_main and test_main. + +int test_main( int argc, char * argv[] ); // prototype for user's test_main() + +int cpp_main( int argc, char * argv[] ) +{ + int result = 0; // quiet compiler warnings + + try + { + result = test_main( argc, argv ); + } + + // The rules for catch & arguments are a bit different from function + // arguments (ISO 15.3 paragraphs 18 & 19). Apparently const isn't + // required, but it doesn't hurt and some programmers ask for it. + + catch ( const boost::test::test_tools_exception & ) + { + std::cout << "\n**** previous test error is fatal" << std::endl; + boost::test::test_tools_errors = 0; // reset so we don't get two messages + result = boost::exit_test_failure; + } + + if ( boost::test::test_tools_errors ) + { + std::cout << "\n**** " << boost::test::test_tools_errors + << " test errors detected" << std::endl; + result = boost::exit_test_failure; + } + + return result; +} diff --git a/include/boost/test/test_tools.hpp b/include/boost/test/test_tools.hpp new file mode 100644 index 00000000..16855847 --- /dev/null +++ b/include/boost/test/test_tools.hpp @@ -0,0 +1,56 @@ +// test tools header -------------------------------------------------------// + +// (C) Copyright Beman Dawes 2000. Permission to copy, use, modify, sell +// and distribute this software is granted provided this copyright notice +// appears in all copies. This software is provided "as is" without express or +// implied warranty, and with no claim as to its suitability for any purpose. + +// See http://www.boost.org for updates, documentation, and revision history. + +// Revision History +// 26 Feb 01 Numerous changes suggested during formal review. (Beman) +// 7 Feb 01 #include if requested. (Beman) +// 22 Jan 01 Remove all header dependencies. (Beman) +// 3 Dec 00 Remove function definitions. (Ed Brey) +// 5 Nov 00 Initial boost version (Beman Dawes) + +#ifndef BOOST_TEST_TOOLS_HPP +#define BOOST_TEST_TOOLS_HPP + +// for convenience, allow the user to request inclusion of lower-level layers +#ifdef BOOST_INCLUDE_MAIN +#include +#include +#endif + +// header dependencies eliminated to reducing coupling. + +// macros (gasp!) ease use of reporting functions + +#define BOOST_TEST(exp) ((exp) ? static_cast(0) : boost::report_error(#exp,__FILE__,__LINE__)) +// Effects: if (!exp) call report_error(). + +#define BOOST_CRITICAL_TEST(exp) ((exp) ? static_cast(0) : boost::report_critical_error(#exp,__FILE__,__LINE__)) +// Effects: if (!exp) call report_critical_error(). + +#define BOOST_ERROR(msg) boost::report_error((msg),__FILE__,__LINE__) + +#define BOOST_CRITICAL_ERROR(msg) boost::report_critical_error((msg),__FILE__,__LINE__) + +namespace boost +{ + // Function implementations are not inline because it is better design to + // decouple implementation, and because space is more important than speed + // since error functions get called relatively infrequently. Note that + // separating implementatiion means that this header could be useful + // without using the boost/test_main.hpp header for a main() function, + // and/or a different implementation could be supplied at link time. + + void report_error( const char * msg, const char * file, int line ); + // Effects: increment test_tools_error counter, write error message to cout. + + void report_critical_error( const char * msg, const char * file, int line ); + // Effects: report_error(msg,file,line), throw test_tools_exception. +} + +#endif // BOOST_TEST_TOOLS_HPP diff --git a/test/regression.cfg b/test/regression.cfg new file mode 100644 index 00000000..e5bdfb79 --- /dev/null +++ b/test/regression.cfg @@ -0,0 +1,14 @@ +// execution tools regression test + +// 25 Jan 01 Initial version (Beman Dawes) + +compile boost/test/cpp_main.cpp +compile boost/test/test_main.cpp +run libs/test/example/cpp_main_example.cpp +run libs/test/example/test_tools_example.cpp +run-fail libs/test/test/test_tools_fail1.cpp +run-fail libs/test/test/test_tools_fail2.cpp +run-fail libs/test/test/test_tools_fail3.cpp +run-fail libs/test/test/test_tools_fail4.cpp + + diff --git a/test/test_tools_fail1.cpp b/test/test_tools_fail1.cpp new file mode 100644 index 00000000..d9905a06 --- /dev/null +++ b/test/test_tools_fail1.cpp @@ -0,0 +1,19 @@ +// test tools - test failure reported via non-zero return value ------------// + +// (C) Copyright Beman Dawes 2000. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. + +// Revision History +// 7 Nov 00 Initial boost version (Beman Dawes) + +// While it would appear that including boost/test_tools.hpp is unneeded, +// it is useful because BOOST_INCLUDE_MAIN is defined. +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include + +int test_main( int, char *[] ) // note the name +{ + return 1; +} \ No newline at end of file diff --git a/test/test_tools_fail2.cpp b/test/test_tools_fail2.cpp new file mode 100644 index 00000000..bc997dfd --- /dev/null +++ b/test/test_tools_fail2.cpp @@ -0,0 +1,22 @@ +// test tools - test failure reported by both macros -----------------------// + +// (C) Copyright Beman Dawes 2000. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. + +// Revision History +// 7 Nov 00 Initial boost version (Beman Dawes) + +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include + +int test_main( int, char *[] ) // note the name +{ + int v = 1; + BOOST_TEST( v == 2 ); + BOOST_ERROR( "sample BOOST_ERROR call" ); + BOOST_CRITICAL_TEST( 2 == v ); + throw "Opps! should never reach this point"; + return 1; +} diff --git a/test/test_tools_fail3.cpp b/test/test_tools_fail3.cpp new file mode 100644 index 00000000..fc34753c --- /dev/null +++ b/test/test_tools_fail3.cpp @@ -0,0 +1,20 @@ +// test tools - test failure reported by BOOST_TEST ------------------------// + +// (C) Copyright Beman Dawes 2000. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. + +// Revision History +// 7 Nov 00 Initial boost version (Beman Dawes) + +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include + +int test_main( int, char *[] ) // note the name +{ + int v = 1; + BOOST_TEST( v == 2 ); + BOOST_TEST( 2 == v ); + return 0; +} \ No newline at end of file diff --git a/test/test_tools_fail4.cpp b/test/test_tools_fail4.cpp new file mode 100644 index 00000000..00a82713 --- /dev/null +++ b/test/test_tools_fail4.cpp @@ -0,0 +1,18 @@ +// test tools - test failure reported by throwing exception ----------------// + +// (C) Copyright Beman Dawes 2001. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. + +// Revision History +// 8 Feb 01 Initial boost version (Beman Dawes) + +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include + +int test_main( int, char *[] ) // note the name +{ + throw "Test error by throwing C-style string exception"; + return 0; +} \ No newline at end of file