rice2 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/COPYING +23 -0
- data/Doxyfile +2268 -0
- data/Makefile.am +26 -0
- data/Makefile.in +929 -0
- data/README.md +1054 -0
- data/README.mingw +8 -0
- data/Rakefile +24 -0
- data/aclocal.m4 +1090 -0
- data/bootstrap +8 -0
- data/config.guess +1667 -0
- data/config.sub +1793 -0
- data/configure +8209 -0
- data/configure.ac +55 -0
- data/depcomp +791 -0
- data/doxygen.ac +314 -0
- data/doxygen.am +186 -0
- data/extconf.rb +66 -0
- data/install-sh +529 -0
- data/missing +215 -0
- data/post-autoconf.rb +22 -0
- data/post-automake.rb +28 -0
- data/rice/Address_Registration_Guard.cpp +22 -0
- data/rice/Address_Registration_Guard.hpp +7 -0
- data/rice/Address_Registration_Guard.ipp +37 -0
- data/rice/Address_Registration_Guard_defn.hpp +75 -0
- data/rice/Arg.hpp +8 -0
- data/rice/Arg_impl.hpp +129 -0
- data/rice/Arg_operators.cpp +21 -0
- data/rice/Arg_operators.hpp +19 -0
- data/rice/Array.hpp +214 -0
- data/rice/Array.ipp +256 -0
- data/rice/Builtin_Object.hpp +8 -0
- data/rice/Builtin_Object.ipp +50 -0
- data/rice/Builtin_Object_defn.hpp +50 -0
- data/rice/Class.cpp +57 -0
- data/rice/Class.hpp +8 -0
- data/rice/Class.ipp +6 -0
- data/rice/Class_defn.hpp +83 -0
- data/rice/Constructor.hpp +47 -0
- data/rice/Data_Object.hpp +8 -0
- data/rice/Data_Object.ipp +133 -0
- data/rice/Data_Object_defn.hpp +138 -0
- data/rice/Data_Type.cpp +54 -0
- data/rice/Data_Type.hpp +8 -0
- data/rice/Data_Type.ipp +365 -0
- data/rice/Data_Type_defn.hpp +261 -0
- data/rice/Data_Type_fwd.hpp +12 -0
- data/rice/Director.cpp +13 -0
- data/rice/Director.hpp +39 -0
- data/rice/Enum.hpp +117 -0
- data/rice/Enum.ipp +246 -0
- data/rice/Exception.cpp +59 -0
- data/rice/Exception.hpp +13 -0
- data/rice/Exception_Base.hpp +8 -0
- data/rice/Exception_Base.ipp +13 -0
- data/rice/Exception_Base_defn.hpp +27 -0
- data/rice/Exception_defn.hpp +69 -0
- data/rice/Hash.hpp +227 -0
- data/rice/Hash.ipp +329 -0
- data/rice/Identifier.cpp +8 -0
- data/rice/Identifier.hpp +50 -0
- data/rice/Identifier.ipp +33 -0
- data/rice/Jump_Tag.hpp +24 -0
- data/rice/Makefile.am +122 -0
- data/rice/Makefile.in +885 -0
- data/rice/Module.cpp +84 -0
- data/rice/Module.hpp +8 -0
- data/rice/Module.ipp +6 -0
- data/rice/Module_defn.hpp +88 -0
- data/rice/Module_impl.hpp +281 -0
- data/rice/Module_impl.ipp +345 -0
- data/rice/Object.cpp +169 -0
- data/rice/Object.hpp +8 -0
- data/rice/Object.ipp +33 -0
- data/rice/Object_defn.hpp +214 -0
- data/rice/Require_Guard.hpp +21 -0
- data/rice/String.cpp +94 -0
- data/rice/String.hpp +91 -0
- data/rice/Struct.cpp +117 -0
- data/rice/Struct.hpp +162 -0
- data/rice/Struct.ipp +26 -0
- data/rice/Symbol.cpp +25 -0
- data/rice/Symbol.hpp +66 -0
- data/rice/Symbol.ipp +44 -0
- data/rice/config.hpp +47 -0
- data/rice/config.hpp.in +46 -0
- data/rice/detail/Arguments.hpp +118 -0
- data/rice/detail/Auto_Function_Wrapper.hpp +898 -0
- data/rice/detail/Auto_Function_Wrapper.ipp +3694 -0
- data/rice/detail/Auto_Member_Function_Wrapper.hpp +897 -0
- data/rice/detail/Auto_Member_Function_Wrapper.ipp +2774 -0
- data/rice/detail/Caster.hpp +103 -0
- data/rice/detail/Exception_Handler.hpp +8 -0
- data/rice/detail/Exception_Handler.ipp +68 -0
- data/rice/detail/Exception_Handler_defn.hpp +96 -0
- data/rice/detail/Iterator.hpp +93 -0
- data/rice/detail/Not_Copyable.hpp +25 -0
- data/rice/detail/Wrapped_Function.hpp +33 -0
- data/rice/detail/cfp.hpp +24 -0
- data/rice/detail/cfp.ipp +51 -0
- data/rice/detail/check_ruby_type.cpp +27 -0
- data/rice/detail/check_ruby_type.hpp +23 -0
- data/rice/detail/creation_funcs.hpp +37 -0
- data/rice/detail/creation_funcs.ipp +36 -0
- data/rice/detail/default_allocation_func.hpp +23 -0
- data/rice/detail/default_allocation_func.ipp +11 -0
- data/rice/detail/define_method_and_auto_wrap.hpp +31 -0
- data/rice/detail/define_method_and_auto_wrap.ipp +30 -0
- data/rice/detail/demangle.cpp +56 -0
- data/rice/detail/demangle.hpp +19 -0
- data/rice/detail/env.hpp +11 -0
- data/rice/detail/from_ruby.hpp +43 -0
- data/rice/detail/from_ruby.ipp +60 -0
- data/rice/detail/method_data.cpp +92 -0
- data/rice/detail/method_data.hpp +21 -0
- data/rice/detail/node.hpp +13 -0
- data/rice/detail/protect.cpp +29 -0
- data/rice/detail/protect.hpp +34 -0
- data/rice/detail/ruby.hpp +74 -0
- data/rice/detail/ruby_version_code.hpp +6 -0
- data/rice/detail/ruby_version_code.hpp.in +6 -0
- data/rice/detail/st.hpp +22 -0
- data/rice/detail/to_ruby.hpp +22 -0
- data/rice/detail/to_ruby.ipp +36 -0
- data/rice/detail/traits.hpp +43 -0
- data/rice/detail/win32.hpp +16 -0
- data/rice/detail/wrap_function.hpp +66 -0
- data/rice/global_function.hpp +33 -0
- data/rice/global_function.ipp +22 -0
- data/rice/protect.hpp +38 -0
- data/rice/protect.ipp +1134 -0
- data/rice/ruby_mark.hpp +13 -0
- data/rice/ruby_try_catch.hpp +86 -0
- data/rice/rubypp.rb +97 -0
- data/rice/to_from_ruby.hpp +8 -0
- data/rice/to_from_ruby.ipp +418 -0
- data/rice/to_from_ruby_defn.hpp +70 -0
- data/ruby.ac +135 -0
- data/ruby/Makefile.am +1 -0
- data/ruby/Makefile.in +628 -0
- data/ruby/lib/Makefile.am +3 -0
- data/ruby/lib/Makefile.in +506 -0
- data/ruby/lib/mkmf-rice.rb.in +217 -0
- data/ruby/lib/version.rb +3 -0
- data/sample/Makefile.am +47 -0
- data/sample/Makefile.in +489 -0
- data/sample/enum/extconf.rb +3 -0
- data/sample/enum/sample_enum.cpp +54 -0
- data/sample/enum/test.rb +8 -0
- data/sample/inheritance/animals.cpp +98 -0
- data/sample/inheritance/extconf.rb +3 -0
- data/sample/inheritance/test.rb +7 -0
- data/sample/map/extconf.rb +3 -0
- data/sample/map/map.cpp +81 -0
- data/sample/map/test.rb +7 -0
- data/test/Makefile.am +72 -0
- data/test/Makefile.in +1213 -0
- data/test/ext/Makefile.am +41 -0
- data/test/ext/Makefile.in +483 -0
- data/test/ext/t1/Foo.hpp +10 -0
- data/test/ext/t1/extconf.rb +2 -0
- data/test/ext/t1/t1.cpp +15 -0
- data/test/ext/t2/extconf.rb +2 -0
- data/test/ext/t2/t2.cpp +11 -0
- data/test/test_Address_Registration_Guard.cpp +43 -0
- data/test/test_Array.cpp +248 -0
- data/test/test_Builtin_Object.cpp +71 -0
- data/test/test_Class.cpp +496 -0
- data/test/test_Constructor.cpp +128 -0
- data/test/test_Data_Object.cpp +275 -0
- data/test/test_Data_Type.cpp +348 -0
- data/test/test_Director.cpp +308 -0
- data/test/test_Enum.cpp +215 -0
- data/test/test_Exception.cpp +47 -0
- data/test/test_Hash.cpp +212 -0
- data/test/test_Identifier.cpp +70 -0
- data/test/test_Jump_Tag.cpp +17 -0
- data/test/test_Memory_Management.cpp +50 -0
- data/test/test_Module.cpp +497 -0
- data/test/test_Object.cpp +159 -0
- data/test/test_String.cpp +107 -0
- data/test/test_Struct.cpp +205 -0
- data/test/test_Symbol.cpp +63 -0
- data/test/test_To_From_Ruby.cpp +428 -0
- data/test/test_global_functions.cpp +114 -0
- data/test/test_rice.rb +41 -0
- data/test/unittest.cpp +136 -0
- data/test/unittest.hpp +294 -0
- metadata +297 -0
@@ -0,0 +1,114 @@
|
|
1
|
+
#include "unittest.hpp"
|
2
|
+
#include "rice/global_function.hpp"
|
3
|
+
|
4
|
+
using namespace Rice;
|
5
|
+
|
6
|
+
TESTSUITE(GlobalFunction);
|
7
|
+
|
8
|
+
SETUP(GlobalFunction)
|
9
|
+
{
|
10
|
+
ruby_init();
|
11
|
+
}
|
12
|
+
|
13
|
+
namespace {
|
14
|
+
|
15
|
+
bool method_to_wrap_called = false;
|
16
|
+
void method_to_wrap(Object self) {
|
17
|
+
method_to_wrap_called = true;
|
18
|
+
}
|
19
|
+
|
20
|
+
int method_with_args_arg0;
|
21
|
+
|
22
|
+
void method_with_args(Object self, int arg) {
|
23
|
+
method_with_args_arg0 = arg;
|
24
|
+
}
|
25
|
+
|
26
|
+
}
|
27
|
+
|
28
|
+
TESTCASE(exposes_global_functions)
|
29
|
+
{
|
30
|
+
define_global_function("method_to_wrap", &method_to_wrap);
|
31
|
+
Module m = Module(rb_mKernel);
|
32
|
+
m.call("method_to_wrap");
|
33
|
+
|
34
|
+
ASSERT(method_to_wrap_called);
|
35
|
+
}
|
36
|
+
|
37
|
+
TESTCASE(exposes_global_functions_with_arguments)
|
38
|
+
{
|
39
|
+
define_global_function("method_with_args", &method_with_args);
|
40
|
+
Module m = Module(rb_mKernel);
|
41
|
+
m.call("method_with_args", 10);
|
42
|
+
|
43
|
+
ASSERT_EQUAL(10, method_with_args_arg0);
|
44
|
+
}
|
45
|
+
|
46
|
+
namespace
|
47
|
+
{
|
48
|
+
int defaults_method_one_arg1;
|
49
|
+
int defaults_method_one_arg2;
|
50
|
+
bool defaults_method_one_arg3 = false;
|
51
|
+
|
52
|
+
void defaults_method_one(int arg1, int arg2 = 3, bool arg3 = true)
|
53
|
+
{
|
54
|
+
defaults_method_one_arg1 = arg1;
|
55
|
+
defaults_method_one_arg2 = arg2;
|
56
|
+
defaults_method_one_arg3 = arg3;
|
57
|
+
}
|
58
|
+
|
59
|
+
int defaults_returns(int arg1, int arg2 = 3)
|
60
|
+
{
|
61
|
+
return arg1 * arg2;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
TESTCASE(default_arguments_for_define_global_function)
|
66
|
+
{
|
67
|
+
define_global_function("foo", &defaults_method_one, (Arg("arg1"), Arg("arg2") = (int)3, Arg("arg3") = (bool)true));
|
68
|
+
Module m(rb_mKernel);
|
69
|
+
|
70
|
+
m.call("foo", 2);
|
71
|
+
|
72
|
+
ASSERT_EQUAL(2, defaults_method_one_arg1);
|
73
|
+
ASSERT_EQUAL(3, defaults_method_one_arg2);
|
74
|
+
ASSERT(defaults_method_one_arg3);
|
75
|
+
|
76
|
+
m.call("foo", 11, 10);
|
77
|
+
|
78
|
+
ASSERT_EQUAL(11, defaults_method_one_arg1);
|
79
|
+
ASSERT_EQUAL(10, defaults_method_one_arg2);
|
80
|
+
ASSERT(defaults_method_one_arg3);
|
81
|
+
|
82
|
+
m.call("foo", 22, 33, false);
|
83
|
+
|
84
|
+
ASSERT_EQUAL(22, defaults_method_one_arg1);
|
85
|
+
ASSERT_EQUAL(33, defaults_method_one_arg2);
|
86
|
+
ASSERT(!defaults_method_one_arg3);
|
87
|
+
}
|
88
|
+
|
89
|
+
TESTCASE(default_arguments_for_define_global_function_and_returning)
|
90
|
+
{
|
91
|
+
define_global_function("foo_ret", &defaults_returns, (Arg("arg1"), Arg("arg2") = (int)3));
|
92
|
+
Module m(rb_mKernel);
|
93
|
+
|
94
|
+
Object o = m.call("foo_ret", 2);
|
95
|
+
ASSERT_EQUAL(INT2NUM(6), o.value());
|
96
|
+
|
97
|
+
o = m.call("foo_ret", 5, 10);
|
98
|
+
ASSERT_EQUAL(INT2NUM(50), o.value());
|
99
|
+
}
|
100
|
+
|
101
|
+
namespace {
|
102
|
+
int the_one_default_arg = 0;
|
103
|
+
void method_with_one_default_arg(int num = 4) {
|
104
|
+
the_one_default_arg = num;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
TESTCASE(single_default_argument)
|
109
|
+
{
|
110
|
+
define_global_function("foo", &method_with_one_default_arg, (Arg("num") = (int)4));
|
111
|
+
Module m(rb_mKernel);
|
112
|
+
m.call("foo");
|
113
|
+
ASSERT_EQUAL(4, the_one_default_arg);
|
114
|
+
}
|
data/test/test_rice.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'minitest'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'rbconfig'
|
5
|
+
|
6
|
+
class RiceTest < Minitest::Test
|
7
|
+
# TODO: probably a better way to find this out...
|
8
|
+
VERBOSE = ARGV.include?('-v')
|
9
|
+
|
10
|
+
EXEEXT = RbConfig::CONFIG['EXEEXT']
|
11
|
+
RUBY = RbConfig::CONFIG['RUBY_INSTALL_NAME']
|
12
|
+
|
13
|
+
def test_unittest
|
14
|
+
run_external_test("./unittest#{EXEEXT}")
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_multiple_extensions
|
18
|
+
run_external_test("#{RUBY} test_multiple_extensions.rb")
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_multiple_extensions_with_inheritance
|
22
|
+
run_external_test("#{RUBY} test_multiple_extensions_with_inheritance.rb")
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_multiple_extensions_same_class
|
26
|
+
run_external_test("#{RUBY} test_multiple_extensions_same_class.rb")
|
27
|
+
end
|
28
|
+
|
29
|
+
def run_external_test(executable)
|
30
|
+
if VERBOSE then
|
31
|
+
system(executable)
|
32
|
+
else
|
33
|
+
result = `#{executable}`
|
34
|
+
if $? != 0 then
|
35
|
+
puts result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
raise "Error: $?" if $? != 0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
data/test/unittest.cpp
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
#include <iostream>
|
2
|
+
#include <map>
|
3
|
+
#include "unittest.hpp"
|
4
|
+
|
5
|
+
size_t assertions;
|
6
|
+
|
7
|
+
namespace
|
8
|
+
{
|
9
|
+
|
10
|
+
typedef std::map<std::string, Test_Suite> Test_Suites;
|
11
|
+
Test_Suite * last_test_suite;
|
12
|
+
|
13
|
+
Test_Suites & test_suites()
|
14
|
+
{
|
15
|
+
static Test_Suites test_suites;
|
16
|
+
return test_suites;
|
17
|
+
}
|
18
|
+
|
19
|
+
} // namespace
|
20
|
+
|
21
|
+
Test_Suite & test_suite()
|
22
|
+
{
|
23
|
+
return *last_test_suite;
|
24
|
+
}
|
25
|
+
|
26
|
+
void new_test_suite(std::string const & name)
|
27
|
+
{
|
28
|
+
test_suites()[name] = Test_Suite(name);
|
29
|
+
last_test_suite = &test_suites()[name];
|
30
|
+
}
|
31
|
+
|
32
|
+
std::ostream & operator<<(std::ostream & out, Failure const & failure)
|
33
|
+
{
|
34
|
+
out << "" << failure.test_suite_name_ << ":" << failure.test_case_name_ << ": " << failure.what_;
|
35
|
+
return out;
|
36
|
+
}
|
37
|
+
|
38
|
+
Test_Suite::
|
39
|
+
Test_Suite(std::string const & name)
|
40
|
+
: name_(name)
|
41
|
+
, setup_(0)
|
42
|
+
, teardown_(0)
|
43
|
+
{
|
44
|
+
}
|
45
|
+
|
46
|
+
void Test_Suite::
|
47
|
+
run(Test_Result & result)
|
48
|
+
{
|
49
|
+
for(Test_Cases::iterator it = test_cases_.begin(),
|
50
|
+
end = test_cases_.end();
|
51
|
+
it != end;
|
52
|
+
++it)
|
53
|
+
{
|
54
|
+
try
|
55
|
+
{
|
56
|
+
std::cout << "" << name() << ":" << it->name() << " ";
|
57
|
+
std::cout.flush();
|
58
|
+
if(setup_)
|
59
|
+
{
|
60
|
+
setup_();
|
61
|
+
}
|
62
|
+
it->run();
|
63
|
+
std::cout << ".";
|
64
|
+
}
|
65
|
+
catch(Assertion_Failed const & ex)
|
66
|
+
{
|
67
|
+
std::cout << "F";
|
68
|
+
result.add_failure(Failure(name(), it->name(), ex.what()));
|
69
|
+
}
|
70
|
+
catch(std::exception const & ex)
|
71
|
+
{
|
72
|
+
std::cout << "E";
|
73
|
+
result.add_error(Failure(name(), it->name(), ex.what()));
|
74
|
+
}
|
75
|
+
catch(...)
|
76
|
+
{
|
77
|
+
std::cout << "E";
|
78
|
+
result.add_error(Failure(name(), it->name(), "Unknown exception"));
|
79
|
+
}
|
80
|
+
if(teardown_)
|
81
|
+
{
|
82
|
+
teardown_();
|
83
|
+
}
|
84
|
+
std::cout << std::endl;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
int main()
|
89
|
+
{
|
90
|
+
Test_Result result;
|
91
|
+
size_t num_tests = 0;
|
92
|
+
|
93
|
+
for(Test_Suites::iterator it = test_suites().begin(),
|
94
|
+
end = test_suites().end();
|
95
|
+
it != end;
|
96
|
+
++it)
|
97
|
+
{
|
98
|
+
it->second.run(result);
|
99
|
+
num_tests += it->second.size();
|
100
|
+
}
|
101
|
+
|
102
|
+
std::cout << std::endl;
|
103
|
+
|
104
|
+
std::cout << num_tests << " test(s), "
|
105
|
+
<< assertions << " assertion(s), "
|
106
|
+
<< result.errors().size() << " error(s), "
|
107
|
+
<< result.failures().size() << " failure(s)"
|
108
|
+
<< std::endl;
|
109
|
+
|
110
|
+
if(result.errors().size() > 0)
|
111
|
+
{
|
112
|
+
std::cout << std::endl << "Errors:" << std::endl;
|
113
|
+
for(std::vector<Failure>::const_iterator it = result.errors().begin(),
|
114
|
+
end = result.errors().end();
|
115
|
+
it != end;
|
116
|
+
++it)
|
117
|
+
{
|
118
|
+
std::cout << *it << std::endl;
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
if(result.failures().size() > 0)
|
123
|
+
{
|
124
|
+
std::cout << std::endl << "Failures:" << std::endl;
|
125
|
+
for(std::vector<Failure>::const_iterator it = result.failures().begin(),
|
126
|
+
end = result.failures().end();
|
127
|
+
it != end;
|
128
|
+
++it)
|
129
|
+
{
|
130
|
+
std::cout << *it << std::endl;
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
return (int)result.errors().size() + (int)result.failures().size();
|
135
|
+
}
|
136
|
+
|
data/test/unittest.hpp
ADDED
@@ -0,0 +1,294 @@
|
|
1
|
+
#ifndef unittest__hpp_
|
2
|
+
#define unittest__hpp_
|
3
|
+
|
4
|
+
/*! \file
|
5
|
+
* \brief A (very) simple unit test framework.
|
6
|
+
*/
|
7
|
+
|
8
|
+
#if defined(_MSC_VER)
|
9
|
+
#define NOMINMAX
|
10
|
+
#endif
|
11
|
+
|
12
|
+
#include <vector>
|
13
|
+
#include <string>
|
14
|
+
#include <stdexcept>
|
15
|
+
#include <sstream>
|
16
|
+
#include <iostream>
|
17
|
+
|
18
|
+
#if !defined(_MSC_VER)
|
19
|
+
using namespace std;
|
20
|
+
#endif
|
21
|
+
|
22
|
+
class Failure
|
23
|
+
{
|
24
|
+
public:
|
25
|
+
Failure(
|
26
|
+
std::string const & test_suite_name,
|
27
|
+
std::string const & test_case_name,
|
28
|
+
std::string what)
|
29
|
+
: test_suite_name_(test_suite_name)
|
30
|
+
, test_case_name_(test_case_name)
|
31
|
+
, what_(what)
|
32
|
+
{
|
33
|
+
}
|
34
|
+
|
35
|
+
friend std::ostream & operator<<(std::ostream & out, Failure const & failure);
|
36
|
+
|
37
|
+
private:
|
38
|
+
std::string test_suite_name_;
|
39
|
+
std::string test_case_name_;
|
40
|
+
std::string what_;
|
41
|
+
};
|
42
|
+
|
43
|
+
class Test_Result
|
44
|
+
{
|
45
|
+
public:
|
46
|
+
void add_failure(Failure const & failure)
|
47
|
+
{
|
48
|
+
failures_.push_back(failure);
|
49
|
+
}
|
50
|
+
|
51
|
+
void add_error(Failure const & failure)
|
52
|
+
{
|
53
|
+
errors_.push_back(failure);
|
54
|
+
}
|
55
|
+
|
56
|
+
std::vector<Failure> const & failures() const
|
57
|
+
{
|
58
|
+
return failures_;
|
59
|
+
}
|
60
|
+
|
61
|
+
std::vector<Failure> const & errors() const
|
62
|
+
{
|
63
|
+
return errors_;
|
64
|
+
}
|
65
|
+
|
66
|
+
private:
|
67
|
+
std::vector<Failure> failures_;
|
68
|
+
std::vector<Failure> errors_;
|
69
|
+
};
|
70
|
+
|
71
|
+
class Test_Case
|
72
|
+
{
|
73
|
+
public:
|
74
|
+
typedef void (*Func)();
|
75
|
+
|
76
|
+
Test_Case(
|
77
|
+
std::string const & name,
|
78
|
+
Func f)
|
79
|
+
: name_(name)
|
80
|
+
, f_(f)
|
81
|
+
{
|
82
|
+
}
|
83
|
+
|
84
|
+
void run()
|
85
|
+
{
|
86
|
+
f_();
|
87
|
+
}
|
88
|
+
|
89
|
+
std::string const & name() const { return name_; }
|
90
|
+
|
91
|
+
size_t size() const { return 1; }
|
92
|
+
|
93
|
+
private:
|
94
|
+
std::string name_;
|
95
|
+
Func f_;
|
96
|
+
};
|
97
|
+
|
98
|
+
class Test_Suite
|
99
|
+
{
|
100
|
+
public:
|
101
|
+
Test_Suite(std::string const & name = "");
|
102
|
+
|
103
|
+
void add_test_case(Test_Case const & test_case)
|
104
|
+
{
|
105
|
+
test_cases_.push_back(test_case);
|
106
|
+
}
|
107
|
+
|
108
|
+
void setup(void (*f)()) { setup_ = f; }
|
109
|
+
void teardown(void (*f)()) { teardown_ = f; }
|
110
|
+
|
111
|
+
void run(Test_Result & result);
|
112
|
+
|
113
|
+
std::string const & name() const { return name_; }
|
114
|
+
|
115
|
+
size_t size() const { return test_cases_.size(); }
|
116
|
+
|
117
|
+
private:
|
118
|
+
std::string name_;
|
119
|
+
|
120
|
+
typedef std::vector<Test_Case> Test_Cases;
|
121
|
+
Test_Cases test_cases_;
|
122
|
+
|
123
|
+
void (*setup_)();
|
124
|
+
void (*teardown_)();
|
125
|
+
};
|
126
|
+
|
127
|
+
|
128
|
+
Test_Suite & test_suite();
|
129
|
+
void new_test_suite(std::string const & name);
|
130
|
+
|
131
|
+
class Assertion_Failed
|
132
|
+
: public std::runtime_error
|
133
|
+
{
|
134
|
+
public:
|
135
|
+
Assertion_Failed(std::string const & what)
|
136
|
+
: std::runtime_error(what)
|
137
|
+
{
|
138
|
+
}
|
139
|
+
};
|
140
|
+
|
141
|
+
|
142
|
+
// TODO: not sure how to append __LINE__ correctly here
|
143
|
+
#define UNIQUE_SUITE_NAME(prefix, name) \
|
144
|
+
prefix ## __ ## name \
|
145
|
+
|
146
|
+
#define TESTSUITE(name) \
|
147
|
+
struct UNIQUE_SUITE_NAME(testsuite_append, name) \
|
148
|
+
{ \
|
149
|
+
UNIQUE_SUITE_NAME(testsuite_append, name)() \
|
150
|
+
{ \
|
151
|
+
new_test_suite(#name); \
|
152
|
+
} \
|
153
|
+
} UNIQUE_SUITE_NAME(testsuite_append__initializer, name)
|
154
|
+
|
155
|
+
#define TESTCASE(name) \
|
156
|
+
static void UNIQUE_SUITE_NAME(test, name)(); \
|
157
|
+
\
|
158
|
+
namespace \
|
159
|
+
{ \
|
160
|
+
struct UNIQUE_SUITE_NAME(test_append, name) \
|
161
|
+
{ \
|
162
|
+
UNIQUE_SUITE_NAME(test_append, name)() \
|
163
|
+
{ \
|
164
|
+
test_suite().add_test_case( \
|
165
|
+
Test_Case(#name, & UNIQUE_SUITE_NAME(test, name))); \
|
166
|
+
} \
|
167
|
+
} UNIQUE_SUITE_NAME(test_append__initializer, name); \
|
168
|
+
} \
|
169
|
+
\
|
170
|
+
static void UNIQUE_SUITE_NAME(test, name)()
|
171
|
+
|
172
|
+
#define TESTFIXTURE(name, type) \
|
173
|
+
static void UNIQUE_SUITE_NAME(fixture ## __ ## name, type)(); \
|
174
|
+
\
|
175
|
+
namespace \
|
176
|
+
{ \
|
177
|
+
struct UNIQUE_SUITE_NAME(fixture_append ## __ ## name, type) \
|
178
|
+
{ \
|
179
|
+
UNIQUE_SUITE_NAME(fixture_append ## __ ## name, type)() \
|
180
|
+
{ \
|
181
|
+
test_suite().type(UNIQUE_SUITE_NAME(fixture ## __ ## name, type)); \
|
182
|
+
} \
|
183
|
+
} UNIQUE_SUITE_NAME(fixture_append__initializer ## __ ## name, type); \
|
184
|
+
} \
|
185
|
+
\
|
186
|
+
static void UNIQUE_SUITE_NAME(fixture ## __ ## name, type)()
|
187
|
+
|
188
|
+
#define SETUP(name) TESTFIXTURE(name, setup)
|
189
|
+
|
190
|
+
#define TEARDOWN(name) TESTFIXTURE(name, teardown)
|
191
|
+
|
192
|
+
template<typename RHS_T, typename LHS_T>
|
193
|
+
inline bool is_equal(RHS_T const & rhs, LHS_T const & lhs)
|
194
|
+
{
|
195
|
+
return rhs == lhs;
|
196
|
+
}
|
197
|
+
|
198
|
+
inline bool is_equal(char const * lhs, char const * rhs)
|
199
|
+
{
|
200
|
+
return std::string(lhs) == std::string(rhs);
|
201
|
+
}
|
202
|
+
|
203
|
+
inline bool is_equal(char * lhs, char const * rhs)
|
204
|
+
{
|
205
|
+
return std::string(lhs) == std::string(rhs);
|
206
|
+
}
|
207
|
+
|
208
|
+
inline bool is_equal(char const * lhs, char * rhs)
|
209
|
+
{
|
210
|
+
return std::string(lhs) == std::string(rhs);
|
211
|
+
}
|
212
|
+
|
213
|
+
template<typename T, typename U>
|
214
|
+
inline bool is_not_equal(T const & t, U const & u)
|
215
|
+
{
|
216
|
+
return !is_equal(t, u);
|
217
|
+
}
|
218
|
+
|
219
|
+
extern size_t assertions;
|
220
|
+
|
221
|
+
template<typename T, typename U>
|
222
|
+
void assert_equal(
|
223
|
+
T const & t,
|
224
|
+
U const & u,
|
225
|
+
std::string const & s_t,
|
226
|
+
std::string const & s_u,
|
227
|
+
std::string const & file,
|
228
|
+
size_t line)
|
229
|
+
{
|
230
|
+
if(!is_equal(t, u))
|
231
|
+
{
|
232
|
+
std::stringstream strm;
|
233
|
+
strm << "Assertion failed: "
|
234
|
+
<< s_t << " != " << s_u
|
235
|
+
<< " (" << t << " != " << u << ")"
|
236
|
+
<< " at " << file << ":" << line;
|
237
|
+
throw Assertion_Failed(strm.str());
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
template<typename T, typename U>
|
242
|
+
void assert_not_equal(
|
243
|
+
T const & t,
|
244
|
+
U const & u,
|
245
|
+
std::string const & s_t,
|
246
|
+
std::string const & s_u,
|
247
|
+
std::string const & file,
|
248
|
+
size_t line)
|
249
|
+
{
|
250
|
+
if(!is_not_equal(t, u))
|
251
|
+
{
|
252
|
+
std::stringstream strm;
|
253
|
+
strm << "Assertion failed: "
|
254
|
+
<< s_t << " should != " << s_u
|
255
|
+
<< " (" << t << " should != " << u << ")"
|
256
|
+
<< " at " << file << ":" << line;
|
257
|
+
throw Assertion_Failed(strm.str());
|
258
|
+
}
|
259
|
+
}
|
260
|
+
|
261
|
+
#define ASSERT_EQUAL(x, y) \
|
262
|
+
do \
|
263
|
+
{ \
|
264
|
+
++assertions; \
|
265
|
+
assert_equal((x), (y), #x, #y, __FILE__, __LINE__); \
|
266
|
+
} while(0)
|
267
|
+
|
268
|
+
#define ASSERT_NOT_EQUAL(x, y) \
|
269
|
+
do \
|
270
|
+
{ \
|
271
|
+
++assertions; \
|
272
|
+
assert_not_equal((x), (y), #x, #y, __FILE__, __LINE__); \
|
273
|
+
} while(0)
|
274
|
+
|
275
|
+
#define ASSERT(x) \
|
276
|
+
ASSERT_EQUAL(true, !!x);
|
277
|
+
|
278
|
+
#define ASSERT_EXCEPTION_CHECK(type, code, check_exception) \
|
279
|
+
try \
|
280
|
+
{ \
|
281
|
+
++assertions; \
|
282
|
+
code; \
|
283
|
+
ASSERT(!"Expected exception"); \
|
284
|
+
} \
|
285
|
+
catch(type const & ex) \
|
286
|
+
{ \
|
287
|
+
check_exception; \
|
288
|
+
}
|
289
|
+
|
290
|
+
#define ASSERT_EXCEPTION(type, code) \
|
291
|
+
ASSERT_EXCEPTION_CHECK(type, code, )
|
292
|
+
|
293
|
+
#endif
|
294
|
+
|