2
This patch adds missing files to 1.2.1 tarball.
4
diff -urN liblas-1.2.1/test/unit/common.hpp main/test/unit/common.hpp
5
--- liblas-1.2.1/test/unit/common.hpp 1970-01-01 01:00:00.000000000 +0100
6
+++ main/test/unit/common.hpp 2009-10-02 16:46:22.000000000 +0200
10
+// (C) Copyright Mateusz Loskot 2008, mateusz@loskot.net
11
+// Distributed under the BSD License
12
+// (See accompanying file LICENSE.txt or copy at
13
+// http://www.opensource.org/licenses/bsd-license.php)
15
+#include <liblas/liblas.hpp>
16
+#include <liblas/laspoint.hpp>
17
+#include <liblas/lasheader.hpp>
23
+// Predicate testing LASPoint against given XY coordinates
27
+ is_xy(double x, double y, double tolerance)
28
+ : x(x), y(y), t(tolerance)
31
+ bool operator()(liblas::LASPoint const& p)
33
+ double const dx = x - p.GetX();
34
+ double const dy = y - p.GetY();
36
+ return ((dx <= t && dx >= -t) && (dy <= t && dy >= -t));
44
+// Functor to calculate bounding box of a set of points
45
+struct bbox_calculator
47
+ // bbox object will store operation result
48
+ bbox_calculator(liblas::detail::Extents<double>& bbox)
49
+ : empty(true), bbox(bbox)
52
+ void operator()(liblas::LASPoint const& p)
54
+ // Box initialization during first iteration only
57
+ bbox.min.x = bbox.max.x = p.GetX();
58
+ bbox.min.y = bbox.max.y = p.GetY();
59
+ bbox.min.z = bbox.max.z = p.GetZ();
63
+ // Expand bounding box to include given point
64
+ bbox.min.x = std::min(bbox.min.x, p.GetX());
65
+ bbox.min.y = std::min(bbox.min.y, p.GetY());
66
+ bbox.min.z = std::min(bbox.min.z, p.GetZ());
67
+ bbox.max.x = std::max(bbox.max.x, p.GetX());
68
+ bbox.max.y = std::max(bbox.max.y, p.GetY());
69
+ bbox.max.z = std::max(bbox.max.z, p.GetZ());
73
+ liblas::detail::Extents<double>& bbox;
76
+// Common test procedure for default constructed point data.
77
+void test_default_point(liblas::LASPoint const& p);
79
+// Common test procedure for default constructed header data.
80
+void test_default_header(liblas::LASHeader const& h);
82
+// Test of header data in trunk/test/data/TO_core_last_clip.las file
83
+void test_file10_header(liblas::LASHeader const& h);
85
+// Test of 1st point record in trunk/test/data/TO_core_last_clip.las file
86
+void test_file10_point1(liblas::LASPoint const& p);
88
+// Test of 2nd point record in trunk/test/data/TO_core_last_clip.las file
89
+void test_file10_point2(liblas::LASPoint const& p);
91
+// Test of 4th point record in trunk/test/data/TO_core_last_clip.las file
92
+void test_file10_point4(liblas::LASPoint const& p);
96
diff -urN liblas-1.2.1/test/unit/liblas_test.hpp main/test/unit/liblas_test.hpp
97
--- liblas-1.2.1/test/unit/liblas_test.hpp 1970-01-01 01:00:00.000000000 +0100
98
+++ main/test/unit/liblas_test.hpp 2009-10-02 16:46:22.000000000 +0200
102
+// (C) Copyright Mateusz Loskot 2008, mateusz@loskot.net
103
+// Distributed under the BSD License
104
+// (See accompanying file LICENSE.txt or copy at
105
+// http://www.opensource.org/licenses/bsd-license.php)
107
+#ifndef LIBLAS_TEST_HPP_INCLUDED
108
+#define LIBLAS_TEST_HPP_INCLUDED
112
+ // full path to trunk/test/data
113
+ extern std::string g_test_data_path;
116
+#endif // LIBLAS_TEST_HPP_INCLUDED
118
diff -urN liblas-1.2.1/test/unit/tut/README main/test/unit/tut/README
119
--- liblas-1.2.1/test/unit/tut/README 1970-01-01 01:00:00.000000000 +0100
120
+++ main/test/unit/tut/README 2009-10-02 16:46:36.000000000 +0200
122
+--------------------------------------------------------------------
123
+TUT: C++ Template Unit Test Framework
125
+Version: TUT-2007-07-06
126
+Homepage: http://tut-framework.sourceforge.net/
127
+--------------------------------------------------------------------
129
+Documentation TUT How-To minimum steps to make TUT work for you
133
+TUT is a pure C++ unit test framework. Its name - TUT - stands for
134
+Template Unit Tests.
138
+TUT provides all features required for unit testing:
140
+ * Similar tests can be grouped together into test groups. Each
141
+ test group has its unique name and is located in a separate
142
+ compilation unit. One group can contain almost unlimited number
143
+ of tests (actually, the limit is the compiler template
145
+ * User can run all the tests (regression), or just some selected
146
+ groups or even some tests in these groups.
147
+ * TUT provides special template functions to check the condition
148
+ validity at run-time and to force test failure if required.
149
+ Since C++ doesn't provide a facility for obtaining stack trace
150
+ of the throwed exception and TUT avoids macros, those functions
151
+ accept string marker to allow users easely determine the source
153
+ * TUT contains callback that can be implemented by the calling code
154
+ to integrate with an IDE, for example. Callbacks tell listener
155
+ when a new test run started, when test runner switches to the
156
+ next tests group, when a test was completed (and what result it
157
+ has), and when test run was finished. The callbacks allow users
158
+ to produce their own visualization format for test process and results.
159
+ * Being a template library, it doesn't need compilation; just
160
+ include the <tut.h> header into the test modules.
162
+TUT tests organization
166
+C++ produces executable code, so tests have to be compiled into a single
167
+binary called test application. The application can be built in automated
168
+mode to perform nightly tests. They also can be built manually when a
169
+developer hunts for bugs.
171
+The test application contains tests, organized into test groups.
175
+The functionality of a tested application can be divided into a few separate
176
+function blocks (e.g. User Rights, Export, Processing, ...). It is natural
177
+to group together tests for each block. TUT invokes this test group. Each
178
+test group has a unique human-readable name and normally is located in a
183
+Each single test usually checks only one specific element of functionality.
184
+For example, for a container a test could check whether size() call
185
+returns zero after the successful call to the clear() method.
191
+You are going to create a new class for your application. You decided to
192
+write tests for the class to be sure it works while you are developing or,
193
+possibly, enhancing it. Let's consider your class is shared pointer:
194
+std::auto_ptr-alike type that shares the same object among instances.
196
+Prior to test writing, you should decide what to test. Maximalist's
197
+approach requires to write so many tests that altering any single
198
+line of your production code will break at least one of them.
199
+Minimalist's approach allows one to write tests only for the most
200
+general or the most complex use cases. The truth lies somewhere in
201
+between, but only you, developer, know where. You should prepare
202
+common successful and unsuccessful scenarios, and the scenarios for
203
+testing any other functionality you believe might be broken in some way.
205
+For our shared_ptr we obviosly should test constructors, assignment operators, referencing and passing ownership.
209
+If you don't have any implemented class to test yet, it would be good to
210
+implement it as a set of stubs for a first time. Thus you'll get an
211
+interface, and be able to write your tests. Yes, that's correct: you
212
+should write your tests before writing code! First of all, writing tests
213
+often helps to understand oddities in the current interface, and fix it.
214
+Secondly, with the stubs all your tests will fail, so you'll be sure
219
+Since we're writing unit tests, it would be a good idea to group the
220
+tests for our class in one place to be able to run them separately.
221
+It's also natural in C++ to place all the grouped tests into one
222
+compilation unit (i.e. source file). So, to begin, we should create
223
+a new file. Let's call it test_shared_ptr.cpp. (Final variant of the
224
+test group can be found in examples/shared_ptr subdirectory of the
225
+distribution package)
227
+// test_shared_ptr.cpp
235
+As you see, you need to include TUT header file (as expected) and
236
+use namespace tut for tests. You may also use anonymous namespace if
237
+your compiler allows it (you will need to instantiate methods from
238
+tut namespace and some compilers refuse to place such instantiations
239
+into the anonymous namespace).
241
+A test group in TUT framework is described by the special template
242
+test_group<T>. The template parameter T is a type that will hold all
243
+test-specific data during the test execution. Actually, the data
244
+stored in T are member data of the test. Test object is inherited
245
+from T, so any test can refer to the data in T as its member data.
247
+For simple test groups (where all data are stored in test local
248
+variables) type T is an empty struct.
254
+ struct shared_ptr_data
259
+But when tests have complex or repeating creation phase, you may put
260
+data members into the T and provide constructor (and, if required,
261
+destructor) for it. For each test, a new instance of T will be
262
+created. To prepare your test for execution TUT will use default
263
+constructor. Similarly, after the test has been finished, TUT
264
+calls the destructor to clean up T. I.e.:
270
+ struct complex_data
273
+ complex_data(){ con = db_pool.get_connection(); }
274
+ ~complex_data(){ db_pool.release_connection(con); }
277
+ // each test from now will have con data member initialized
284
+What will happen if the constructor throws an exception? TUT will treat
285
+it as if test itself failed with exception, so this test will
286
+not be executed. You'll see an exception mark near the test, and
287
+if the constructor throwed something printable, a certain message will appear.
289
+Exception in destructor is threated a bit different. Reaching destruction
290
+phase means that the test is passed, so TUT marks test with warning
291
+status meaning that test itself was OK, but something bad has happend
294
+Well, all we have written so far is just a type declaration. To work
295
+with a group we have to have an object, so we must create the test group
296
+object. Since we need only one test group object for each unit, we can
297
+(and should, actually) make this object static. To prevent name clash with
298
+other test group objects in the namespace tut, we should provide a
299
+descriptive name, or, alternatively, we may put it into the anonymous
300
+namespace. The former is more correct, but a descriptive name usually works
301
+well too, unless you're too terse in giving names to objects.
307
+ struct shared_ptr_data
312
+ typedef test_group<shared_ptr_data> tg;
313
+ tg shared_ptr_group("shared_ptr");
316
+As you see, any test group accepts a single parameter - its human-readable
317
+name. This name is used to identify the group when a programmer wants to
318
+execute all tests or a single test within the group. So this name shall
319
+also be descriptive enough to avoid clashes. Since we're writing tests
320
+for a specific unit, it's enough to name it after the unit name.
322
+Test group constructor will be called at unspecified moment at the test
323
+application startup. The constructor performs self-registration; it calls
324
+tut::runner and asks it to store the test group object name and location.
325
+Any other test group in the system undergoes the same processing, i.e.
326
+each test group object registers itself. Thus, test runner can iterate
327
+all test groups or execute any test group by its name.
329
+Newly created group has no tests associated with it. To be more precise,
330
+it has predefined set of dummy tests. By default, there are 50 tests in a
331
+group, including dummy ones. To create a test group with higher volume
332
+(e.g. when tests are generated by a script and their number is higher)
333
+we must provide a higher border of test group size when it is instantiated:
339
+ struct huge_test_data
343
+ // test group with maximum 500 tests
344
+ typedef test_group<huge_test_data,500> testgroup;
345
+ testgroup huge_test_testgroup("huge group");
349
+Note also, that your compiler will possibly need a command-line switch
350
+or pragma to enlarge recursive instantiation depth. For g++, for
351
+example, you should specify at least --ftemplate-depth-501 to increase
352
+the depth. For more information see your compiler documentation.
356
+Now it's time to fill our test group with content.
358
+In TUT, all tests have unique numbers inside the test group. Some
359
+people believe that textual names better describe failed tests in
360
+reports. I agree; but in reality C++ templates work good with numbers
361
+because they are compile-time constants and refuse to do the same
362
+with strings, since strings are in fact addresses of character
363
+buffers, i.e. run-time data.
365
+As I mentioned above, our test group already has a few dummy tests;
366
+and we can replace any of them with something real just by writing
373
+ struct shared_ptr_data{};
375
+ typedef test_group<shared_ptr_data> testgroup;
376
+ typedef testgroup::object testobject;
377
+ testgroup shared_ptr_testgroup("shared_ptr");
381
+ void testobject::test<1>()
388
+So far this test does nothing, but it's enough to illustrate the concept.
390
+All tests in the group belong to the type test_group<T>::object. This
391
+class is directly inherited from our test data structure. In our case, it is
393
+class object : public shared_ptr_data { ... }
395
+This allows to access members of the data structure directly, since at
396
+the same time they are members of the object type. We also typedef the
397
+type with testobject for brevity.
399
+We mark our test with number 1. Previously, test group had a dummy test
400
+with the same number, but now, since we've defined our own version, it
401
+replaces the dummy test as more specialized one. It's how C++ template
404
+The test we've written always succeeds. Successful test returns with no
405
+exceptions. Unsuccessful one either throws an exception, or fails at
406
+fail() or ensure() methods (which anyway just throw the exception when failed).
410
+Well, now we know enough to write the first real working test. This test
411
+will create shared_ptr instances and check their state. We will define a
412
+small structure (keepee) to use it as shared_ptr stored object type.
415
+#include <shared_ptr.h>
419
+ struct shared_ptr_data
421
+ struct keepee{ int data; };
424
+ typedef test_group<shared_ptr_data> testgroup;
425
+ typedef testgroup::object testobject;
426
+ testgroup shared_ptr_testgroup("shared_ptr");
429
+ * Checks default constructor.
433
+ void testobject::test<1>()
435
+ shared_ptr<keepee> def;
436
+ ensure("null",def.get() == 0);
441
+That's all! The first line creates shared_ptr. If constructor throws
442
+an exception, test will fail (exceptions, including '...', are catched
443
+by the TUT framework). If the first line succeeds, we must check
444
+whether the kept object is null one. To do this, we use test object
445
+member function ensure(), which throws std::logic_error with a given
446
+message if its second argument is not true. Finally, if destructor of
447
+shared_ptr fails with exception, TUT also will report this test as failed.
449
+It's equally easy to write a test for the scenario where we expect to get
450
+an exception: let's consider our class should throw an exception if it
451
+has no stored object, and the operator -> is called.
454
+ * Checks operator -> throws instead of returning null.
458
+void testobject::test<2>()
462
+ shared_ptr<keepee> sp;
464
+ fail("exception expected");
466
+ catch( const std::runtime_error& ex )
473
+Here we expect the std::runtime_error. If operator doesn't throw it,
474
+we'll force the test to fail using another member function: fail(). It
475
+just throws std::logic_error with a given message. If operator throws
476
+anything else, our test will fail too, since we intercept only
477
+std::runtime_error, and any other exception means the test has failed.
479
+NB: our second test has number 2 in its name; it can, actually, be any
480
+in range 1..Max; the only requirement is not to write tests with the
481
+same numbers. If you did, compiler will force you to fix them anyway.
483
+And finally, one more test to demonstrate how to use the
484
+ensure_equals template member function:
487
+ * Checks keepee counting.
491
+void testobject::test<3>()
493
+ shared_ptr<keepee> sp1(new keepee());
494
+ shared_ptr<keepee> sp2(sp1);
495
+ ensure_equals("second copy at sp1",sp1.count(),2);
496
+ ensure_equals("second copy at sp2",sp2.count(),2);
500
+The test checks if the shared_ptr correctly counts references during
501
+copy construction. What's interesting here is the template member
502
+ensure_equals. It has an additional functionality comparing with similar
503
+call ensure("second_copy",sp1.count()==2); it uses operator == to check
504
+the equality of the two passed parameters and, what's more important, it
505
+uses std::stream to format the passed parameters into a human-readable
506
+message (smth like: "second copy: expected 2, got 1"). It means that
507
+ensure_equals cannot be used with the types that don't have operator <<;
508
+but for those having the operator it provides much more informational message.
510
+In contrast to JUnit assertEquals, where the expected value goes before
511
+the actual one, ensure_equals() accepts the expected after the actual
512
+value. I believe it's more natural to read ensure_equals("msg", count, 5)
513
+as "ensure that count equals to 5" rather than JUnit's
514
+"assert that 5 is the value of the count".
518
+Tests are already written, but an attempt to run them will be unsuccessful.
519
+We need a few other bits to complete the test application.
521
+First of all, we need a main() method, simply because it must be in all
522
+applications. Secondly, we need a test runner singleton. Remember I said
523
+each test group should register itself in singleton? So, we need that
524
+singleton. And, finally, we need a kind of a callback handler to visualize
527
+The design of TUT doesn't strictly set a way the tests are visualized;
528
+instead, it provides an opportunity to get the test results by means of
529
+callbacks. Moreover it allows user to output the results in any format he
530
+prefers. Of course, there is a "reference implementation" in the
531
+example/subdirectory of the project.
533
+Test runner singleton is defined in tut.h, so all we need to activate it
534
+is to declare an object of the type tut::test_runner_singleton in the main
535
+module with a special name tut::runner.
537
+Now, with the test_runner we can run tests. Singleton has method get()
538
+returning a reference to an instance of the test_runner class, which in
539
+turn has methods run_tests() to run all tests in all groups,
540
+run_tests(const std::string& groupname) to run all tests in a given group
541
+and run_test(const std::string& grp,int n) to run one test in the specified group.
548
+ test_runner_singleton runner;
553
+ // run all tests in all groups
554
+ runner.get().run_tests();
556
+ // run all tests in group "shared_ptr"
557
+ runner.get().run_tests("shared_ptr");
559
+ // run test number 5 in group "shared_ptr"
560
+ runner.get().run_test("shared_ptr",5);
565
+It's up to user to handle command-line arguments or GUI messages and map those
566
+arguments/messages to actual calls to test runner. Again, as you see, TUT
567
+doesn't restrict user here.
569
+But, the last question is still unanswered: how do we get our test results?
570
+The answer lies inside tut::callback interface. User shall create its subclass,
571
+and write up to three simple methods. He also can omit any method since they
572
+have default no-op implementation. Each corresponding method is called in the
575
+ * a new test run started;
577
+ * test run finished.
579
+Here is a minimal implementation:
581
+class visualizator : public tut::callback
584
+ void run_started(){ }
586
+ void test_completed(const tut::test_result& tr)
588
+ // ... show test result here ...
591
+ void run_completed(){ }
594
+The most important is the test_completed() method; its parameter has type
595
+test_result, and contains everything about the finished test, from its group
596
+name and number to the exception message, if any. Member result is an enum
597
+that contains status of the test: ok, fail or ex. Take a look at the
598
+examples/basic/main.cpp for more complete visualizator.
600
+Visualizator should be passed to the test_runner before run. Knowing that,
601
+we are ready to write the final version of our main module:
608
+ test_runner_singleton runner;
611
+class callback : public tut::callback
614
+ void run_started(){ std::cout << "\nbegin"; }
616
+ void test_completed(const tut::test_result& tr)
618
+ std::cout << tr.test_pos << "=" << tr.result << std::flush;
621
+ void run_completed(){ std::cout << "\nend"; }
627
+ runner.get().set_callback(&clbk);
629
+ // run all tests in all groups
630
+ runner.get().run_tests();
634
+That's it. You are now ready to link and run our test application. Do it as often as possible;
635
+once a day is a definite must. I hope, TUT will help you to make your application more
636
+robust and relieve your testing pain. Feel free to send your questions, suggestions and
637
+critical opinions to me; I'll do my best to address them asap.
638
diff -urN liblas-1.2.1/test/unit/tut/tut.hpp main/test/unit/tut/tut.hpp
639
--- liblas-1.2.1/test/unit/tut/tut.hpp 1970-01-01 01:00:00.000000000 +0100
640
+++ main/test/unit/tut/tut.hpp 2009-10-02 16:46:36.000000000 +0200
651
+// NOTE: mloskot added for ensure_equals<double,double> specialization
655
+#if defined(TUT_USE_SEH)
656
+#include <windows.h>
657
+#include <winbase.h>
661
+ * Template Unit Tests Framework for C++.
662
+ * http://tut.dozen.ru
664
+ * @author Vladimir Dyuzhev, Vladimir.Dyuzhev@gmail.com
670
+ * The base for all TUT exceptions.
672
+struct tut_error : public std::exception
674
+ tut_error(const std::string& msg)
679
+ ~tut_error() throw()
683
+ const char* what() const throw()
685
+ return err_msg.c_str();
690
+ std::string err_msg;
694
+ * Exception to be throwed when attempted to execute
695
+ * missed test by number.
697
+struct no_such_test : public tut_error
700
+ : tut_error("no such test")
704
+ ~no_such_test() throw()
710
+ * No such test and passed test number is higher than
711
+ * any test number in current group. Used in one-by-one
712
+ * test running when upper bound is not known.
714
+struct beyond_last_test : public no_such_test
720
+ ~beyond_last_test() throw()
726
+ * Group not found exception.
728
+struct no_such_group : public tut_error
730
+ no_such_group(const std::string& grp)
735
+ ~no_such_group() throw()
741
+ * Internal exception to be throwed when
742
+ * no more tests left in group or journal.
744
+struct no_more_tests
750
+ ~no_more_tests() throw()
756
+ * Internal exception to be throwed when
757
+ * test constructor has failed.
759
+struct bad_ctor : public tut_error
761
+ bad_ctor(const std::string& msg)
766
+ ~bad_ctor() throw()
772
+ * Exception to be throwed when ensure() fails or fail() called.
774
+struct failure : public tut_error
776
+ failure(const std::string& msg)
787
+ * Exception to be throwed when test desctructor throwed an exception.
789
+struct warning : public tut_error
791
+ warning(const std::string& msg)
802
+ * Exception to be throwed when test issued SEH (Win32)
804
+struct seh : public tut_error
806
+ seh(const std::string& msg)
817
+ * Return type of runned test/test group.
819
+ * For test: contains result of test and, possible, message
820
+ * for failure or exception.
830
+ * Test number in group.
835
+ * Test name (optional)
840
+ * ok - test finished successfully
841
+ * fail - test failed with ensure() or fail() methods
842
+ * ex - test throwed an exceptions
843
+ * warn - test finished successfully, but test destructor throwed
844
+ * term - test forced test application to terminate abnormally
856
+ result_type result;
859
+ * Exception message for failed test.
861
+ std::string message;
862
+ std::string exception_typeid;
865
+ * Default constructor.
876
+ test_result(const std::string& grp, int pos,
877
+ const std::string& test_name, result_type res)
886
+ * Constructor with exception.
888
+ test_result(const std::string& grp,int pos,
889
+ const std::string& test_name, result_type res,
890
+ const std::exception& ex)
895
+ message(ex.what()),
896
+ exception_typeid(typeid(ex).name())
903
+ * Test group operations.
907
+ virtual ~group_base()
911
+ // execute tests iteratively
912
+ virtual void rewind() = 0;
913
+ virtual test_result run_next() = 0;
915
+ // execute one test
916
+ virtual test_result run_test(int n) = 0;
920
+ * Test runner callback interface.
921
+ * Can be implemented by caller to update
922
+ * tests results in real-time. User can implement
923
+ * any of callback methods, and leave unused
924
+ * in default implementation.
929
+ * Virtual destructor is a must for subclassed types.
931
+ virtual ~callback()
936
+ * Called when new test run started.
938
+ virtual void run_started()
943
+ * Called when a group started
944
+ * @param name Name of the group
946
+ virtual void group_started(const std::string& /*name*/)
951
+ * Called when a test finished.
952
+ * @param tr Test results.
954
+ virtual void test_completed(const test_result& /*tr*/)
959
+ * Called when a group is completed
960
+ * @param name Name of the group
962
+ virtual void group_completed(const std::string& /*name*/)
967
+ * Called when all tests in run completed.
969
+ virtual void run_completed()
975
+ * Typedef for runner::list_groups()
977
+typedef std::vector<std::string> groupnames;
991
+ : callback_(&default_callback_)
996
+ * Stores another group for getting by name.
998
+ void register_group(const std::string& name, group_base* gr)
1002
+ throw tut_error("group shall be non-null");
1005
+ // TODO: inline variable
1006
+ groups::iterator found = groups_.find(name);
1007
+ if (found != groups_.end())
1009
+ std::string msg("attempt to add already existent group " + name);
1010
+ // this exception terminates application so we use cerr also
1011
+ // TODO: should this message appear in stream?
1012
+ std::cerr << msg << std::endl;
1013
+ throw tut_error(msg);
1016
+ groups_[name] = gr;
1020
+ * Stores callback object.
1022
+ void set_callback(callback* cb)
1024
+ callback_ = cb == 0 ? &default_callback_ : cb;
1028
+ * Returns callback object.
1030
+ callback& get_callback() const
1032
+ return *callback_;
1036
+ * Returns list of known test groups.
1038
+ const groupnames list_groups() const
1041
+ const_iterator i = groups_.begin();
1042
+ const_iterator e = groups_.end();
1045
+ ret.push_back(i->first);
1052
+ * Runs all tests in all groups.
1053
+ * @param callback Callback object if exists; null otherwise
1055
+ void run_tests() const
1057
+ callback_->run_started();
1059
+ const_iterator i = groups_.begin();
1060
+ const_iterator e = groups_.end();
1063
+ callback_->group_started(i->first);
1066
+ run_all_tests_in_group_(i);
1068
+ catch (const no_more_tests&)
1070
+ callback_->group_completed(i->first);
1076
+ callback_->run_completed();
1080
+ * Runs all tests in specified group.
1082
+ void run_tests(const std::string& group_name) const
1084
+ callback_->run_started();
1086
+ const_iterator i = groups_.find(group_name);
1087
+ if (i == groups_.end())
1089
+ callback_->run_completed();
1090
+ throw no_such_group(group_name);
1093
+ callback_->group_started(group_name);
1096
+ run_all_tests_in_group_(i);
1098
+ catch (const no_more_tests&)
1103
+ callback_->group_completed(group_name);
1104
+ callback_->run_completed();
1108
+ * Runs one test in specified group.
1110
+ test_result run_test(const std::string& group_name, int n) const
1112
+ callback_->run_started();
1114
+ const_iterator i = groups_.find(group_name);
1115
+ if (i == groups_.end())
1117
+ callback_->run_completed();
1118
+ throw no_such_group(group_name);
1121
+ callback_->group_started(group_name);
1124
+ test_result tr = i->second->run_test(n);
1125
+ callback_->test_completed(tr);
1126
+ callback_->group_completed(group_name);
1127
+ callback_->run_completed();
1130
+ catch (const beyond_last_test&)
1132
+ callback_->group_completed(group_name);
1133
+ callback_->run_completed();
1136
+ catch (const no_such_test&)
1138
+ callback_->group_completed(group_name);
1139
+ callback_->run_completed();
1146
+ typedef std::map<std::string, group_base*> groups;
1147
+ typedef groups::iterator iterator;
1148
+ typedef groups::const_iterator const_iterator;
1151
+ callback default_callback_;
1152
+ callback* callback_;
1157
+ void run_all_tests_in_group_(const_iterator i) const
1159
+ i->second->rewind();
1162
+ test_result tr = i->second->run_next();
1163
+ callback_->test_completed(tr);
1165
+ if (tr.result == test_result::ex_ctor)
1167
+ throw no_more_tests();
1174
+ * Singleton for test_runner implementation.
1175
+ * Instance with name runner_singleton shall be implemented
1178
+class test_runner_singleton
1182
+ static test_runner& get()
1184
+ static test_runner tr;
1189
+extern test_runner_singleton runner;
1192
+ * Test object. Contains data test run upon and default test method
1193
+ * implementation. Inherited from Data to allow tests to
1194
+ * access test data as members.
1196
+template <class Data>
1197
+class test_object : public Data
1202
+ * Default constructor
1208
+ void set_test_name(const std::string& current_test_name)
1210
+ current_test_name_ = current_test_name;
1213
+ const std::string& get_test_name() const
1215
+ return current_test_name_;
1219
+ * Default do-nothing test.
1224
+ called_method_was_a_dummy_test_ = true;
1228
+ * The flag is set to true by default (dummy) test.
1229
+ * Used to detect usused test numbers and avoid unnecessary
1230
+ * test object creation which may be time-consuming depending
1231
+ * on operations described in Data::Data() and Data::~Data().
1232
+ * TODO: replace with throwing special exception from default test.
1234
+ bool called_method_was_a_dummy_test_;
1238
+ std::string current_test_name_;
1245
+ * Tests provided condition.
1246
+ * Throws if false.
1248
+void ensure(bool cond)
1252
+ // TODO: default ctor?
1253
+ throw failure("");
1258
+ * Tests provided condition.
1261
+void ensure_not(bool cond)
1267
+ * Tests provided condition.
1268
+ * Throws if false.
1270
+template <typename T>
1271
+void ensure(const T msg, bool cond)
1275
+ throw failure(msg);
1280
+ * Tests provided condition.
1283
+template <typename T>
1284
+void ensure_not(const T msg, bool cond)
1286
+ ensure(msg, !cond);
1290
+ * Tests two objects for being equal.
1291
+ * Throws if false.
1293
+ * NB: both T and Q must have operator << defined somewhere, or
1294
+ * client code will not compile at all!
1296
+template <class T, class Q>
1297
+void ensure_equals(const char* msg, const Q& actual, const T& expected)
1299
+ if (expected != actual)
1301
+ std::stringstream ss;
1302
+ ss << (msg ? msg : "")
1303
+ << (msg ? ":" : "")
1309
+ throw failure(ss.str().c_str());
1313
+template <class T, class Q>
1314
+void ensure_equals(const Q& actual, const T& expected)
1316
+ ensure_equals<>(0, actual, expected);
1320
+ * Specialization of ensure_equals for double type.
1321
+ * NOTE: unofficial extension added by mloskot
1324
+void ensure_equals<double, double>(const char* msg, const double& actual, const double& expected)
1326
+ const double epsilon = std::numeric_limits<double>::epsilon();
1327
+ const double diff = actual - expected;
1329
+ if ( !((diff <= epsilon) && (diff >= -epsilon )) )
1331
+ std::stringstream ss;
1332
+ ss << (msg?msg:"") << (msg?": ":"")
1333
+ << std::scientific << std::showpoint << std::setprecision(16)
1334
+ << "expected " << expected
1335
+ << " actual " << actual
1336
+ << " with precision " << epsilon;
1337
+ throw failure(ss.str().c_str());
1342
+void ensure_equals<double, double>(const double& actual, const double& expected)
1344
+ ensure_equals<>(0, actual, expected);
1348
+ * Tests two objects for being at most in given distance one from another.
1349
+ * Borders are excluded.
1350
+ * Throws if false.
1352
+ * NB: T must have operator << defined somewhere, or
1353
+ * client code will not compile at all! Also, T shall have
1354
+ * operators + and -, and be comparable.
1357
+void ensure_distance(const char* msg, const T& actual, const T& expected,
1358
+ const T& distance)
1360
+ if (expected-distance >= actual || expected+distance <= actual)
1362
+ std::stringstream ss;
1363
+ ss << (msg ? msg : "")
1364
+ << (msg? ":" : "")
1366
+ << expected-distance
1368
+ << expected+distance
1372
+ throw failure(ss.str().c_str());
1377
+void ensure_distance(const T& actual, const T& expected, const T& distance)
1379
+ ensure_distance<>(0, actual, expected, distance);
1383
+ * Unconditionally fails with message.
1385
+void fail(const char* msg = "")
1387
+ throw failure(msg);
1390
+} // end of namespace
1393
+ * Walks through test tree and stores address of each
1394
+ * test method in group. Instantiation stops at 0.
1396
+template <class Test, class Group, int n>
1397
+struct tests_registerer
1399
+ static void reg(Group& group)
1401
+ group.reg(n, &Test::template test<n>);
1402
+ tests_registerer<Test, Group, n - 1>::reg(group);
1406
+template <class Test, class Group>
1407
+struct tests_registerer<Test, Group, 0>
1409
+ static void reg(Group&)
1415
+ * Test group; used to recreate test object instance for
1416
+ * each new test since we have to have reinitialized
1417
+ * Data base class.
1419
+template <class Data, int MaxTestsInGroup = 50>
1420
+class test_group : public group_base
1422
+ const char* name_;
1424
+ typedef void (test_object<Data>::*testmethod)();
1425
+ typedef std::map<int, testmethod> tests;
1426
+ typedef typename tests::iterator tests_iterator;
1427
+ typedef typename tests::const_iterator tests_const_iterator;
1428
+ typedef typename tests::const_reverse_iterator
1429
+ tests_const_reverse_iterator;
1430
+ typedef typename tests::size_type size_type;
1433
+ tests_iterator current_test_;
1436
+ * Exception-in-destructor-safe smart-pointer class.
1438
+ template <class T>
1442
+ bool permit_throw_in_dtor;
1444
+ safe_holder(const safe_holder&);
1445
+ safe_holder& operator=(const safe_holder&);
1450
+ permit_throw_in_dtor(false)
1459
+ T* operator->() const
1470
+ * Tell ptr it can throw from destructor. Right way is to
1471
+ * use std::uncaught_exception(), but some compilers lack
1472
+ * correct implementation of the function.
1474
+ void permit_throw()
1476
+ permit_throw_in_dtor = true;
1480
+ * Specially treats exceptions in test object destructor;
1481
+ * if test itself failed, exceptions in destructor
1482
+ * are ignored; if test was successful and destructor failed,
1483
+ * warning exception throwed.
1489
+ if (delete_obj() == false)
1491
+ throw warning("destructor of test object raised"
1492
+ " an SEH exception");
1495
+ catch (const std::exception& ex)
1497
+ if (permit_throw_in_dtor)
1499
+ std::string msg = "destructor of test object raised"
1502
+ throw warning(msg);
1507
+ if (permit_throw_in_dtor)
1509
+ throw warning("destructor of test object raised an"
1516
+ * Re-init holder to get brand new object.
1521
+ permit_throw_in_dtor = false;
1527
+#if defined(TUT_USE_SEH)
1534
+#if defined(TUT_USE_SEH)
1536
+ __except(handle_seh_(::GetExceptionCode()))
1538
+ if (permit_throw_in_dtor)
1550
+ typedef test_object<Data> object;
1553
+ * Creates and registers test group with specified name.
1555
+ test_group(const char* name)
1558
+ // register itself
1559
+ runner.get().register_group(name_,this);
1561
+ // register all tests
1562
+ tests_registerer<object, test_group, MaxTestsInGroup>::reg(*this);
1566
+ * This constructor is used in self-test run only.
1568
+ test_group(const char* name, test_runner& another_runner)
1571
+ // register itself
1572
+ another_runner.register_group(name_, this);
1574
+ // register all tests
1575
+ tests_registerer<test_object<Data>, test_group,
1576
+ MaxTestsInGroup>::reg(*this);
1580
+ * Registers test method under given number.
1582
+ void reg(int n, testmethod tm)
1588
+ * Reset test position before first test.
1592
+ current_test_ = tests_.begin();
1598
+ test_result run_next()
1600
+ if (current_test_ == tests_.end())
1602
+ throw no_more_tests();
1605
+ // find next user-specialized test
1606
+ safe_holder<object> obj;
1607
+ while (current_test_ != tests_.end())
1611
+ return run_test_(current_test_++, obj);
1613
+ catch (const no_such_test&)
1619
+ throw no_more_tests();
1623
+ * Runs one test by position.
1625
+ test_result run_test(int n)
1627
+ // beyond tests is special case to discover upper limit
1628
+ if (tests_.rbegin() == tests_.rend())
1630
+ throw beyond_last_test();
1633
+ if (tests_.rbegin()->first < n)
1635
+ throw beyond_last_test();
1638
+ // withing scope; check if given test exists
1639
+ tests_iterator ti = tests_.find(n);
1640
+ if (ti == tests_.end())
1642
+ throw no_such_test();
1645
+ safe_holder<object> obj;
1646
+ return run_test_(ti, obj);
1652
+ * VC allows only one exception handling type per function,
1653
+ * so I have to split the method.
1655
+ * TODO: refactoring needed!
1657
+ test_result run_test_(const tests_iterator& ti, safe_holder<object>& obj)
1659
+ std::string current_test_name;
1662
+ if (run_test_seh_(ti->second,obj, current_test_name) == false)
1667
+ catch (const no_such_test&)
1671
+ catch (const warning& ex)
1673
+ // test ok, but destructor failed
1676
+ current_test_name = obj->get_test_name();
1678
+ test_result tr(name_,ti->first, current_test_name,
1679
+ test_result::warn, ex);
1682
+ catch (const failure& ex)
1684
+ // test failed because of ensure() or similar method
1687
+ current_test_name = obj->get_test_name();
1689
+ test_result tr(name_,ti->first, current_test_name,
1690
+ test_result::fail, ex);
1693
+ catch (const seh& ex)
1695
+ // test failed with sigsegv, divide by zero, etc
1698
+ current_test_name = obj->get_test_name();
1700
+ test_result tr(name_, ti->first, current_test_name,
1701
+ test_result::term, ex);
1704
+ catch (const bad_ctor& ex)
1706
+ // test failed because test ctor failed; stop the whole group
1709
+ current_test_name = obj->get_test_name();
1711
+ test_result tr(name_, ti->first, current_test_name,
1712
+ test_result::ex_ctor, ex);
1715
+ catch (const std::exception& ex)
1717
+ // test failed with std::exception
1720
+ current_test_name = obj->get_test_name();
1722
+ test_result tr(name_, ti->first, current_test_name,
1723
+ test_result::ex, ex);
1728
+ // test failed with unknown exception
1731
+ current_test_name = obj->get_test_name();
1733
+ test_result tr(name_, ti->first, current_test_name,
1739
+ test_result tr(name_,ti->first, current_test_name, test_result::ok);
1744
+ * Runs one under SEH if platform supports it.
1746
+ bool run_test_seh_(testmethod tm, safe_holder<object>& obj,
1747
+ std::string& current_test_name)
1749
+#if defined(TUT_USE_SEH)
1753
+ if (obj.get() == 0)
1755
+ reset_holder_(obj);
1758
+ obj->called_method_was_a_dummy_test_ = false;
1760
+#if defined(TUT_USE_SEH)
1765
+ (obj.get()->*tm)();
1766
+#if defined(TUT_USE_SEH)
1768
+ __except(handle_seh_(::GetExceptionCode()))
1770
+ // throw seh("SEH");
1771
+ current_test_name = obj->get_test_name();
1776
+ if (obj->called_method_was_a_dummy_test_)
1778
+ // do not call obj.release(); reuse object
1779
+ throw no_such_test();
1782
+ current_test_name = obj->get_test_name();
1783
+ obj.permit_throw();
1785
+#if defined(TUT_USE_SEH)
1787
+ __except(handle_seh_(::GetExceptionCode()))
1795
+ void reset_holder_(safe_holder<object>& obj)
1801
+ catch (const std::exception& ex)
1803
+ throw bad_ctor(ex.what());
1807
+ throw bad_ctor("test constructor has generated an exception;"
1808
+ " group execution is terminated");
1813
+#if defined(TUT_USE_SEH)
1815
+ * Decides should we execute handler or ignore SE.
1817
+inline int handle_seh_(DWORD excode)
1821
+ case EXCEPTION_ACCESS_VIOLATION:
1822
+ case EXCEPTION_DATATYPE_MISALIGNMENT:
1823
+ case EXCEPTION_BREAKPOINT:
1824
+ case EXCEPTION_SINGLE_STEP:
1825
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1826
+ case EXCEPTION_FLT_DENORMAL_OPERAND:
1827
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO:
1828
+ case EXCEPTION_FLT_INEXACT_RESULT:
1829
+ case EXCEPTION_FLT_INVALID_OPERATION:
1830
+ case EXCEPTION_FLT_OVERFLOW:
1831
+ case EXCEPTION_FLT_STACK_CHECK:
1832
+ case EXCEPTION_FLT_UNDERFLOW:
1833
+ case EXCEPTION_INT_DIVIDE_BY_ZERO:
1834
+ case EXCEPTION_INT_OVERFLOW:
1835
+ case EXCEPTION_PRIV_INSTRUCTION:
1836
+ case EXCEPTION_IN_PAGE_ERROR:
1837
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
1838
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1839
+ case EXCEPTION_STACK_OVERFLOW:
1840
+ case EXCEPTION_INVALID_DISPOSITION:
1841
+ case EXCEPTION_GUARD_PAGE:
1842
+ case EXCEPTION_INVALID_HANDLE:
1843
+ return EXCEPTION_EXECUTE_HANDLER;
1846
+ return EXCEPTION_CONTINUE_SEARCH;
1853
diff -urN liblas-1.2.1/test/unit/tut/tut_reporter.hpp main/test/unit/tut/tut_reporter.hpp
1854
--- liblas-1.2.1/test/unit/tut/tut_reporter.hpp 1970-01-01 01:00:00.000000000 +0100
1855
+++ main/test/unit/tut/tut_reporter.hpp 2009-10-02 16:46:36.000000000 +0200
1857
+#ifndef TUT_REPORTER
1858
+#define TUT_REPORTER
1860
+#include <tut/tut.hpp>
1863
+ * Template Unit Tests Framework for C++.
1864
+ * http://tut.dozen.ru
1866
+ * @author Vladimir Dyuzhev, Vladimir.Dyuzhev@gmail.com
1871
+std::ostream& operator<<(std::ostream& os, const tut::test_result& tr)
1875
+ case tut::test_result::ok:
1878
+ case tut::test_result::fail:
1879
+ os << '[' << tr.test << "=F]";
1881
+ case tut::test_result::ex_ctor:
1882
+ os << '[' << tr.test << "=C]";
1884
+ case tut::test_result::ex:
1885
+ os << '[' << tr.test << "=X]";
1887
+ case tut::test_result::warn:
1888
+ os << '[' << tr.test << "=W]";
1890
+ case tut::test_result::term:
1891
+ os << '[' << tr.test << "=T]";
1898
+} // end of namespace
1904
+ * Default TUT callback handler.
1906
+class reporter : public tut::callback
1908
+ std::string current_group;
1909
+ typedef std::vector<tut::test_result> not_passed_list;
1910
+ not_passed_list not_passed;
1916
+ int exceptions_count;
1917
+ int failures_count;
1918
+ int terminations_count;
1919
+ int warnings_count;
1927
+ reporter(std::ostream& out)
1933
+ void run_started()
1938
+ void test_completed(const tut::test_result& tr)
1940
+ if (tr.group != current_group)
1942
+ os << std::endl << tr.group << ": " << std::flush;
1943
+ current_group = tr.group;
1946
+ os << tr << std::flush;
1947
+ if (tr.result == tut::test_result::ok)
1951
+ else if (tr.result == tut::test_result::ex)
1953
+ exceptions_count++;
1955
+ else if (tr.result == tut::test_result::ex_ctor)
1957
+ exceptions_count++;
1959
+ else if (tr.result == tut::test_result::fail)
1963
+ else if (tr.result == tut::test_result::warn)
1969
+ terminations_count++;
1972
+ if (tr.result != tut::test_result::ok)
1974
+ not_passed.push_back(tr);
1978
+ void run_completed()
1982
+ if (not_passed.size() > 0)
1984
+ not_passed_list::const_iterator i = not_passed.begin();
1985
+ while (i != not_passed.end())
1987
+ tut::test_result tr = *i;
1991
+ os << "---> " << "group: " << tr.group
1992
+ << ", test: test<" << tr.test << ">"
1993
+ << (!tr.name.empty() ? (std::string(" : ") + tr.name) : std::string())
1996
+ os << " problem: ";
1999
+ case test_result::fail:
2000
+ os << "assertion failed" << std::endl;
2002
+ case test_result::ex:
2003
+ case test_result::ex_ctor:
2004
+ os << "unexpected exception" << std::endl;
2005
+ if( tr.exception_typeid != "" )
2007
+ os << " exception typeid: "
2008
+ << tr.exception_typeid << std::endl;
2011
+ case test_result::term:
2012
+ os << "would be terminated" << std::endl;
2014
+ case test_result::warn:
2015
+ os << "test passed, but cleanup code (destructor) raised"
2016
+ " an exception" << std::endl;
2022
+ if (!tr.message.empty())
2024
+ if (tr.result == test_result::fail)
2026
+ os << " failed assertion: \"" << tr.message << "\""
2031
+ os << " message: \"" << tr.message << "\""
2042
+ os << "tests summary:";
2043
+ if (terminations_count > 0)
2045
+ os << " terminations:" << terminations_count;
2047
+ if (exceptions_count > 0)
2049
+ os << " exceptions:" << exceptions_count;
2051
+ if (failures_count > 0)
2053
+ os << " failures:" << failures_count;
2055
+ if (warnings_count > 0)
2057
+ os << " warnings:" << warnings_count;
2059
+ os << " ok:" << ok_count;
2063
+ bool all_ok() const
2065
+ return not_passed.empty();
2073
+ exceptions_count = 0;
2074
+ failures_count = 0;
2075
+ terminations_count = 0;
2076
+ warnings_count = 0;
2077
+ not_passed.clear();
2084
diff -urN liblas-1.2.1/test/unit/tut/tut_restartable.hpp main/test/unit/tut/tut_restartable.hpp
2085
--- liblas-1.2.1/test/unit/tut/tut_restartable.hpp 1970-01-01 01:00:00.000000000 +0100
2086
+++ main/test/unit/tut/tut_restartable.hpp 2009-10-02 16:46:36.000000000 +0200
2088
+#ifndef TUT_RESTARTABLE_H_GUARD
2089
+#define TUT_RESTARTABLE_H_GUARD
2091
+#include <tut/tut.hpp>
2093
+#include <iostream>
2094
+#include <stdexcept>
2097
+ * Template Unit Tests Framework for C++.
2098
+ * http://tut.dozen.ru
2100
+ * Optional restartable wrapper for test_runner. Allows to restart test runs
2101
+ * finished due to abnormal test application termination (such as segmentation
2102
+ * fault or math error).
2104
+ * @author Vladimir Dyuzhev, Vladimir.Dyuzhev@gmail.com
2114
+ * Escapes non-alphabetical characters in string.
2116
+std::string escape(const std::string& orig)
2119
+ std::string::const_iterator i,e;
2125
+ if ((*i >= 'a' && *i <= 'z') ||
2126
+ (*i >= 'A' && *i <= 'Z') ||
2127
+ (*i >= '0' && *i <= '9') )
2134
+ rc += ('a'+(((unsigned int)*i) >> 4));
2135
+ rc += ('a'+(((unsigned int)*i) & 0xF));
2144
+ * Un-escapes string.
2146
+std::string unescape(const std::string& orig)
2149
+ std::string::const_iterator i,e;
2164
+ throw std::invalid_argument("unexpected end of string");
2166
+ unsigned int c1 = *i;
2170
+ throw std::invalid_argument("unexpected end of string");
2172
+ unsigned int c2 = *i;
2173
+ rc += (((c1 - 'a') << 4) + (c2 - 'a'));
2182
+ * Serialize test_result avoiding interfering with operator <<.
2184
+void serialize(std::ostream& os, const tut::test_result& tr)
2186
+ os << escape(tr.group) << std::endl;
2187
+ os << tr.test << ' ';
2190
+ case test_result::ok:
2193
+ case test_result::fail:
2196
+ case test_result::ex:
2199
+ case test_result::warn:
2202
+ case test_result::term:
2206
+ throw std::logic_error("operator << : bad result_type");
2208
+ os << ' ' << escape(tr.message) << std::endl;
2212
+ * deserialization for test_result
2214
+void deserialize(std::istream& is, tut::test_result& tr)
2216
+ std::getline(is,tr.group);
2219
+ throw tut::no_more_tests();
2221
+ tr.group = unescape(tr.group);
2227
+ throw std::logic_error("operator >> : bad test number");
2235
+ tr.result = test_result::ok;
2238
+ tr.result = test_result::fail;
2241
+ tr.result = test_result::ex;
2244
+ tr.result = test_result::warn;
2247
+ tr.result = test_result::term;
2250
+ throw std::logic_error("operator >> : bad result_type");
2253
+ is.ignore(1); // space
2254
+ std::getline(is,tr.message);
2255
+ tr.message = unescape(tr.message);
2258
+ throw std::logic_error("malformed test result");
2264
+ * Restartable test runner wrapper.
2266
+class restartable_wrapper
2268
+ test_runner& runner_;
2269
+ callback* callback_;
2272
+ std::string log_; // log file: last test being executed
2273
+ std::string jrn_; // journal file: results of all executed tests
2277
+ * Default constructor.
2278
+ * @param dir Directory where to search/put log and journal files
2280
+ restartable_wrapper(const std::string& dir = ".")
2281
+ : runner_(runner.get()),
2285
+ // dozen: it works, but it would be better to use system path separator
2286
+ jrn_ = dir_ + '/' + "journal.tut";
2287
+ log_ = dir_ + '/' + "log.tut";
2291
+ * Stores another group for getting by name.
2293
+ void register_group(const std::string& name, group_base* gr)
2295
+ runner_.register_group(name,gr);
2299
+ * Stores callback object.
2301
+ void set_callback(callback* cb)
2307
+ * Returns callback object.
2309
+ callback& get_callback() const
2311
+ return runner_.get_callback();
2315
+ * Returns list of known test groups.
2317
+ groupnames list_groups() const
2319
+ return runner_.list_groups();
2323
+ * Runs all tests in all groups.
2325
+ void run_tests() const
2327
+ // where last run was failed
2328
+ std::string fail_group;
2330
+ read_log_(fail_group,fail_test);
2331
+ bool fail_group_reached = (fail_group == "");
2333
+ // iterate over groups
2334
+ tut::groupnames gn = list_groups();
2335
+ tut::groupnames::const_iterator gni,gne;
2338
+ while (gni != gne)
2340
+ // skip all groups before one that failed
2341
+ if (!fail_group_reached)
2343
+ if (*gni != fail_group)
2348
+ fail_group_reached = true;
2351
+ // first or restarted run
2352
+ int test = (*gni == fail_group && fail_test >= 0) ? fail_test + 1 : 1;
2355
+ // last executed test pos
2356
+ register_execution_(*gni,test);
2360
+ tut::test_result tr = runner_.run_test(*gni,test);
2361
+ register_test_(tr);
2363
+ catch (const tut::beyond_last_test&)
2367
+ catch(const tut::no_such_test&)
2378
+ // show final results to user
2379
+ invoke_callback_();
2381
+ // truncate files as mark of successful finish
2387
+ * Shows results from journal file.
2389
+ void invoke_callback_() const
2391
+ runner_.set_callback(callback_);
2392
+ runner_.get_callback().run_started();
2394
+ std::string current_group;
2395
+ std::ifstream ijournal(jrn_.c_str());
2396
+ while (ijournal.good())
2398
+ // read next test result
2401
+ tut::test_result tr;
2402
+ util::deserialize(ijournal,tr);
2403
+ runner_.get_callback().test_completed(tr);
2405
+ catch (const no_more_tests&)
2411
+ runner_.get_callback().run_completed();
2415
+ * Register test into journal.
2417
+ void register_test_(const test_result& tr) const
2419
+ std::ofstream ojournal(jrn_.c_str(), std::ios::app);
2420
+ util::serialize(ojournal, tr);
2421
+ ojournal << std::flush;
2422
+ if (!ojournal.good())
2424
+ throw std::runtime_error("unable to register test result in file "
2430
+ * Mark the fact test going to be executed
2432
+ void register_execution_(const std::string& grp, int test) const
2434
+ // last executed test pos
2435
+ std::ofstream olog(log_.c_str());
2436
+ olog << util::escape(grp) << std::endl << test << std::endl << std::flush;
2439
+ throw std::runtime_error("unable to register execution in file "
2447
+ void truncate_() const
2449
+ std::ofstream olog(log_.c_str());
2450
+ std::ofstream ojournal(jrn_.c_str());
2456
+ void read_log_(std::string& fail_group, int& fail_test) const
2458
+ // read failure point, if any
2459
+ std::ifstream ilog(log_.c_str());
2460
+ std::getline(ilog,fail_group);
2461
+ fail_group = util::unescape(fail_group);
2462
+ ilog >> fail_test;
2471
+ // test was terminated...
2472
+ tut::test_result tr(fail_group, fail_test, "", tut::test_result::term);
2473
+ register_test_(tr);