rice2 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|