=head1 NAME Test::Class - Parrot extension for objecty testing of modules =head1 SYNOPSIS .sub 'main' # load this library load_bytecode 'Test/Class.pbc' # load other testing libraries .include 'test_more.pir' .local pmc class class = subclass [ 'Test'; 'Class' ], 'MyClass' .local pmc obj obj = class.'new'() obj.'runtests'() .end .namespace [ 'MyClass' ] .sub 'init' :vtable :method self.'add_startup'( 'startup', 'tests' => 1 ) self.'add_shutdown'( 'shutdown', 'tests' => 1 ) self.'add_setup'( 'setup', 'tests' => 2 ) self.'add_teardown'( 'teardown', 'tests' => 1 ) self.'add_test'( 'test_foo', 'tests' => 3 ) self.'add_test'( 'test_bar', 'tests' => 2 ) .end =head1 DESCRIPTION C is a pure-Parrot library for testing code in a class-y fashion. It allows you to group test code in methods and use other object oriented programming principles to organize and reuse code. Most of your tests will occur within test methods; C runs these automatically for you. THIS INTERFACE MAY CHANGE IN THE NEAR FUTURE. For each test method, you must call C, passing the name of the test method. You may optionally pass the named parameter C with the number of test assertions in the method. You may have as many test methods as you like. C can also run methods at the start of the testing process and after all tests have ended. These are startup and shutdown tests, respectively. Call C and C tests to add each type of test. Again, you may have as many of these methods as you like. Finally, C can run setup and teardown methods before and after I individual test method. Call C and C respectively. When you have finished adding tests, call the C method to run everything. =cut .namespace [ 'Test'; 'Class' ] .sub '__init__' :load load_bytecode 'Test/More.pbc' .local pmc class class = newclass [ 'Test'; 'Class' ] addattribute class, 'test_count' addattribute class, 'setup_test_count' addattribute class, 'teardown_test_count' addattribute class, 'startup' addattribute class, 'setup' addattribute class, 'tests' addattribute class, 'teardown' addattribute class, 'shutdown' addattribute class, 'builder' .end .sub 'init' :vtable :method .local pmc rsa rsa = new 'ResizableStringArray' setattribute self, 'startup', rsa rsa = new 'ResizableStringArray' setattribute self, 'setup', rsa rsa = new 'ResizableStringArray' setattribute self, 'tests', rsa rsa = new 'ResizableStringArray' setattribute self, 'teardown', rsa rsa = new 'ResizableStringArray' setattribute self, 'shutdown', rsa .local pmc count count = new 'Integer' setattribute self, 'test_count', count count = new 'Integer' setattribute self, 'setup_test_count', count count = new 'Integer' setattribute self, 'teardown_test_count', count .local pmc tb tb = new [ 'Test'; 'Builder' ] setattribute self, 'builder', tb .end .sub 'add_startup' :method .param string meth_name .param int tests :optional :named('tests') .param int have_tests :opt_flag .local pmc startup startup = getattribute self, 'startup' push startup, meth_name unless have_tests goto done self.'add_test_count'( tests ) done: .return() .end .sub 'add_setup' :method .param string meth_name .param int tests :optional :named('tests') .param int have_tests :opt_flag .local pmc setup setup = getattribute self, 'setup' push setup, meth_name unless have_tests goto done .local pmc setup_test_count setup_test_count = getattribute self, 'setup_test_count' setup_test_count += tests done: .return() .end .sub 'add_test' :method .param string meth_name .param int test_count :optional :named('tests') .param int have_count :opt_flag .local pmc tests tests = getattribute self, 'tests' push tests, meth_name unless have_count goto done self.'add_test_count'( test_count ) done: .return() .end .sub 'add_teardown' :method .param string meth_name .param int tests :optional :named('tests') .param int have_tests :opt_flag .local pmc teardown teardown = getattribute self, 'teardown' push teardown, meth_name unless have_tests goto done .local pmc teardown_test_count teardown_test_count = getattribute self, 'teardown_test_count' teardown_test_count += tests done: .return() .end .sub 'add_shutdown' :method .param string meth_name .param int tests :optional :named('tests') .param int have_tests :opt_flag .local pmc shutdown shutdown = getattribute self, 'shutdown' push shutdown, meth_name unless have_tests goto done self.'add_test_count'( tests ) done: .return() .end .sub 'add_test_count' :method .param int count .local pmc test_count test_count = getattribute self, 'test_count' test_count += count .return() .end .sub 'runtests' :method .local pmc tb tb = getattribute self, 'builder' .local pmc count count = getattribute self, 'test_count' $I0 = count if $I0 goto set_int_count tb.'plan'( 'no_plan' ) goto run_tests set_int_count: .local int int_count int_count = count .local pmc tests tests = getattribute self, 'tests' .local int num_test_methods num_test_methods = tests .local pmc wrap_count wrap_count = getattribute self, 'setup_test_count' $I0 = wrap_count $I0 *= num_test_methods int_count += $I0 wrap_count = getattribute self, 'teardown_test_count' $I0 = wrap_count $I0 *= num_test_methods int_count += $I0 tb.'plan'( int_count ) run_tests: self.'loop_over_methods'( 'startup' ) self.'loop_over_tests'() self.'loop_over_methods'( 'shutdown' ) tb.'finish'() .end .sub 'loop_over_methods' :method .param string name .local pmc attribute attribute = getattribute self, name .local pmc it it = iter attribute .local string meth_name iter_loop: unless it goto loop_end meth_name = shift it self.meth_name() goto iter_loop loop_end: .return() .end .sub 'loop_over_tests' :method .local pmc tests tests = getattribute self, 'tests' .local pmc it it = iter tests .local string meth_name iter_loop: unless it goto loop_end self.'loop_over_methods'( 'setup' ) meth_name = shift it self.meth_name() self.'loop_over_methods'( 'teardown' ) goto iter_loop loop_end: .return() .end =head1 AUTHOR Written and maintained by chromatic, C<< chromatic at wgz dot org >>, based on Test::Class in Perl 5, L, written by Adrian Howard. Please send patches, feedback, and suggestions to the Perl 6 internals mailing list. =head1 COPYRIGHT Copyright (C) 2008, Parrot Foundation. =cut # Local Variables: # mode: pir # fill-column: 100 # End: # vim: expandtab shiftwidth=4 ft=pir: