>>SOURCE FORMAT FREE *>**** *> GCBLUnit *> *> @author Olegs Kunicins *> @license GPL *> *> This program is free software; you can redistribute it and/or *> modify it under the terms of the GNU General Public License as *> published by the Free Software Foundation; either version 2, *> or (at your option) any later version. *> *> This program is distributed in the hope that it will be useful, *> but WITHOUT ANY WARRANTY; without even the implied warranty of *> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *> GNU General Public License for more details. *> *> You should have received a copy of the GNU General Public *> License along with this software; see the file COPYING. *> If not, write to the Free Software Foundation, Inc., *> 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *>**** >>DEFINE constant VERSION as "1.22.6" identification division. program-id. gcblunit. environment division. configuration section. repository. function all intrinsic. input-output section. file-control. select junit assign to junit-file organization is line sequential file status is junit-file-status. data division. file section. fd junit. 01 junit-line pic x(1024). working-storage section. 78 ASSERTIONS-LIMIT value 999. 78 LINEBREAK value x"0a". 78 COLOR-GREEN value x"1b5b33326d". 78 COLOR-RED value x"1b5b33316d". 78 COLOR-YELLOW value x"1b5b33336d". 78 COLOR-RESET value x"1b5b306d". 01 INTRO. 05 filler pic x(8) value "GCBLUnit". 05 filler pic x. 05 filler pic x(7) value VERSION. 05 filler pic x. 05 filler pic x(35) value "by Olegs Kunicins and contributors.". 01 HELP. 05 filler pic x(80) value "Usage:". 05 filler pic x value LINEBREAK. 05 filler pic x(100) value " cobc -x -debug gcblunit.cbl first-test.cbl [next-test.cbl] --job='first-test [next-test]'". 05 filler pic x value LINEBREAK. 05 filler pic x(80) value " cobc -x -debug gcblunit.cbl --job=Options". 05 filler pic x value LINEBREAK. 05 filler pic x value LINEBREAK. 05 filler pic x(80) value "Options:". 05 filler pic x value LINEBREAK. 05 filler pic x(80) value " -h, -help Print this help". 05 filler pic x value LINEBREAK. 05 filler pic x(80) value " -v, --version Print the version". 05 filler pic x value LINEBREAK. 05 filler pic x(80) value " --stop-on-error Stop on the first error". 05 filler pic x value LINEBREAK. 05 filler pic x(80) value " --stop-on-failure Stop on the first failure". 05 filler pic x value LINEBREAK. 05 filler pic x(80) value " --junit report.xml Report in JUnit XML format". 05 filler pic x value LINEBREAK. 01 assertions-counter usage binary-long unsigned external. 01 summary-pointer usage pointer external. 01 summary. 03 assertions-total usage binary-long unsigned. 03 failures-total usage binary-long unsigned. 03 assertions occurs 0 to ASSERTIONS-LIMIT times depending on assertions-counter. 05 assertion-status pic x. 88 assertion-failed value "F". 05 filler pic x. 05 assertion-suite pic x(32). 05 filler pic x value "#". 05 assertion-nr pic 9(2). 05 filler pic x. 05 assertion-name pic x(16). 05 filler pic x. 05 assertion-expected pic x(32). 05 filler pic x(4) value " <> ". 05 assertion-actual pic x(32). 01 argv pic x(256). 88 option-help value "-h", "--help". 88 option-version value "-v", "--version". 88 option-junit value "--junit". 88 option-stop-on-error value "--stop-on-error". 88 option-stop-on-failure value "--stop-on-failure". 01 junit-file pic x(256). 88 is-empty value SPACE. 01 junit-file-status pic x(2). 88 junit-ok value "00". 01 junit-testsuite. 05 filler pic x(36) value ' '. 01 junit-elapsed-time usage binary-long unsigned. 01 ws-stop-on-error usage binary-short value 0. 01 ws-stop-on-failure usage binary-short value 0. *> local 01 assertions-index usage binary-long unsigned. 01 first-suite pic x(32). 88 is-empty value SPACE. 01 current-time. 05 hours pic 9(2). 05 minutes pic 9(2). 05 seconds pic 9(2). 01 elapsed-time. 05 hours pic 9(2). 05 minutes pic 9(2). 05 seconds pic 9(2). 77 test-pointer usage program-pointer. 88 test-skipped value NULL. 01 testsuite-name pic x(128). 01 tests-total usage binary-long unsigned. 01 skipped-total usage binary-long unsigned. 01 errors-total usage binary-long unsigned. procedure division. *> accept tmp-dir from environment "TMPDIR". *> call "CBL_GET_CURRENT_DIR" using by value 0, by value 255, by reference current-dir. perform cblu-start. accept argv from ARGUMENT-VALUE. perform until argv = SPACE evaluate TRUE when option-help display HELP stop run when option-version stop run when option-junit move SPACE to argv accept argv from ARGUMENT-VALUE move argv to junit-file when option-stop-on-error move 1 to ws-stop-on-error when option-stop-on-failure move 1 to ws-stop-on-failure when other move argv to testsuite-name perform cblu-exec if ws-stop-on-failure = 1 and failures-total > 0 exit perform end-if if ws-stop-on-error = 1 and errors-total > 0 exit perform end-if end-evaluate move SPACE to argv accept argv from ARGUMENT-VALUE end-perform. perform cblu-finish. if not is-empty of junit-file perform cblu-junit end-if. stop run. cblu-start section. set environment "COB_SCREEN_EXCEPTIONS" to 'Y'. set environment "COB_DISPLAY_WARNINGS" to 'Y'. set environment "COB_SET_DEBUG" to 'Y'. set summary-pointer to address of summary. display INTRO LINEBREAK. >>IF DEBUG IS NOT SET display "Warning: debug mode disabled" >>END-IF accept elapsed-time from TIME. cblu-exec section. call "CBL_EXIT_PROC" using 0, address of entry "interruption-handler". call "CBL_ERROR_PROC" using 0, address of entry "exception-handler". set test-pointer to entry testsuite-name. if test-skipped add 1 to skipped-total else add 1 to tests-total call test-pointer end-if. if EXCEPTION-STATUS <> SPACE and trim(EXCEPTION-LOCATION) (1:length(trim(testsuite-name))) = trim(testsuite-name) add 1 to errors-total display LINEBREAK "There was an exception: " trim(EXCEPTION-STATUS) " in " EXCEPTION-LOCATION " on " EXCEPTION-STATEMENT end-if. call "CBL_ERROR_PROC" using 1, address of entry "exception-handler". call "CBL_EXIT_PROC" using 1, address of entry "interruption-handler". cblu-finish section. accept current-time from TIME. subtract corresponding current-time from elapsed-time. *> time display LINEBREAK LINEBREAK "Time: " hours of elapsed-time ":" minutes of elapsed-time ":" seconds of elapsed-time. *> failures if failures-total of summary > 0 display "There was " failures-total of summary " failure(s):" end-if. move 0 to assertions-index. perform until assertions-index >= assertions-total of summary add 1 to assertions-index if assertion-failed(assertions-index) display assertions(assertions-index) end-if end-perform. *> report display LINEBREAK. if errors-total > 0 display COLOR-RED "EXCEPTIONS!" COLOR-RESET move 1 to RETURN-CODE end-if. if failures-total of summary > 0 display COLOR-RED "FAILURES!" COLOR-RESET move 1 to RETURN-CODE end-if. if errors-total = 0 and failures-total of summary = 0 if tests-total > 0 and assertions-total of summary > 0 display COLOR-GREEN "OK" COLOR-RESET else if tests-total = 0 display COLOR-YELLOW "No tests found" COLOR-RESET else display COLOR-YELLOW "No assertions found" COLOR-RESET end-if end-if move 0 to RETURN-CODE end-if. display "Tests: " tests-total ", Skipped: " skipped-total LINEBREAK "Assertions: " assertions-total of summary ", Failures: " failures-total of summary ", Exceptions: " errors-total. cblu-junit section. open output junit. if not junit-ok display "Error writing " junit-file ": " junit-file-status upon syserr end-if. *> cover move '' to junit-line. write junit-line. move '' to junit-line. write junit-line. move tests-total to junit-tests of junit-testsuite. move skipped-total to junit-skipped of junit-testsuite. move assertions-total to junit-assertions of junit-testsuite. move failures-total to junit-failures of junit-testsuite. move errors-total to junit-errors of junit-testsuite. compute junit-elapsed-time = 3600 * hours of elapsed-time + 60 * minutes of elapsed-time + seconds of elapsed-time. move junit-elapsed-time to junit-time. move junit-testsuite to junit-line. write junit-line. *> cases move 0 to assertions-index. perform until assertions-index >= assertions-total of summary add 1 to assertions-index *> suite if first-suite <> assertion-suite(assertions-index) if not is-empty of first-suite move ' ' to junit-line write junit-line end-if move concatenate( ' ' ) to junit-line write junit-line move assertion-suite(assertions-index) to first-suite end-if *> case move concatenate( ' ' ) to junit-line write junit-line *> failure if assertion-failed(assertions-index) move concatenate( ' ' ) to junit-line write junit-line end-if *> /case move ' ' to junit-line write junit-line end-perform. move ' ' to junit-line write junit-line move ' ' to junit-line write junit-line. move '' to junit-line write junit-line. close junit. if not junit-ok display "Error closing " junit-file ": " junit-file-status upon syserr end-if. identification division. program-id. exception-handler. environment division. data division. working-storage section. procedure division. end program exception-handler. identification division. program-id. interruption-handler. environment division. data division. working-storage section. procedure division. display SPACE. display "Tests were interruped in " MODULE-SOURCE. end program interruption-handler. end program gcblunit. identification division. program-id. assert-equals. environment division. configuration section. repository. function all intrinsic. data division. working-storage section. 78 ASSERTIONS-LIMIT value 999. 01 assertions-counter usage binary-long unsigned external. 01 summary-pointer usage pointer external. 01 assertions-nr pic 9(2). *> local 01 comparison usage binary-long. 01 idx usage binary-long unsigned. 01 diff-idx usage binary-long. 01 diff-length usage binary-long unsigned. 01 diff-numeric usage binary-long based. linkage section. 01 expected pic x any length. 01 actual pic x any length. 01 summary. 03 assertions-total usage binary-long unsigned. 03 failures-total usage binary-long unsigned. 03 assertions occurs 0 to ASSERTIONS-LIMIT times depending on assertions-counter. 05 assertion-status pic x. 88 assertion-failed value "F". 05 filler pic x. 05 assertion-suite pic x(32). 05 filler pic x value "#". 05 assertion-nr pic 9(2). 05 filler pic x. 05 assertion-name pic x(16). 05 filler pic x. 05 assertion-expected pic x(32). 05 filler pic x(4) value " <> ". 05 assertion-actual pic x(32). procedure division using expected, actual. set address of summary to summary-pointer. add 1 to assertions-total. add 1 to assertions-nr. add 1 to assertions-counter. move assertions-nr to assertion-nr(assertions-counter). move MODULE-ID to assertion-name(assertions-counter). move MODULE-CALLER-ID to assertion-suite(assertions-counter). move 0 to idx. move 0 to comparison. perform until idx >= byte-length(actual) or idx >= byte-length(expected) add 1 to idx compute comparison = ord(expected(idx:1)) - ord(actual(idx:1)) if comparison <> 0 exit perform end-if end-perform. if comparison = 0 move "." to assertion-status(assertions-counter) else move "F" to assertion-status(assertions-counter) add 1 to failures-total end-if. *> show status display assertion-status(assertions-counter) with no advancing. *> show diff compute diff-length = byte-length(assertion-expected(assertions-counter)). compute diff-idx = idx - (0.5 * diff-length - 1). if diff-idx < 1 move 1 to diff-idx end-if. if diff-length + diff-idx > byte-length(expected) compute diff-length = byte-length(expected) - diff-idx + 1 end-if. move expected(diff-idx:diff-length) to assertion-expected(assertions-counter). compute diff-length = byte-length(assertion-actual(assertions-counter)). compute diff-idx = idx - (0.5 * diff-length - 1). if diff-idx < 1 move 1 to diff-idx end-if. if diff-length + diff-idx > byte-length(actual) compute diff-length = byte-length(actual) - diff-idx + 1 end-if. move actual(diff-idx:diff-length) to assertion-actual(assertions-counter). end program assert-equals. identification division. program-id. assert-notequals. environment division. configuration section. repository. function all intrinsic. data division. working-storage section. 78 ASSERTIONS-LIMIT value 999. 01 assertions-counter usage binary-long unsigned external. 01 summary-pointer usage pointer external. 01 assertions-nr pic 9(2). *> local 01 comparison usage binary-long. 01 idx usage binary-long unsigned. 01 diff-idx usage binary-long. 01 diff-length usage binary-long unsigned. 01 diff-numeric usage binary-long based. linkage section. 01 expected pic x any length. 01 actual pic x any length. 01 summary. 03 assertions-total usage binary-long unsigned. 03 failures-total usage binary-long unsigned. 03 assertions occurs 0 to ASSERTIONS-LIMIT times depending on assertions-counter. 05 assertion-status pic x. 88 assertion-failed value "F". 05 filler pic x. 05 assertion-suite pic x(32). 05 filler pic x value "#". 05 assertion-nr pic 9(2). 05 filler pic x. 05 assertion-name pic x(16). 05 filler pic x. 05 assertion-expected pic x(32). 05 filler pic x(4) value " <> ". 05 assertion-actual pic x(32). procedure division using expected, actual. set address of summary to summary-pointer. add 1 to assertions-total. add 1 to assertions-nr. add 1 to assertions-counter. move assertions-nr to assertion-nr(assertions-counter). move MODULE-ID to assertion-name(assertions-counter). move MODULE-CALLER-ID to assertion-suite(assertions-counter). move 0 to idx. move 0 to comparison. perform until idx >= byte-length(actual) or idx >= byte-length(expected) add 1 to idx compute comparison = ord(expected(idx:1)) - ord(actual(idx:1)) if comparison <> 0 exit perform end-if end-perform. if comparison <> 0 move "." to assertion-status(assertions-counter) else move "F" to assertion-status(assertions-counter) add 1 to failures-total end-if. *> show status display assertion-status(assertions-counter) with no advancing. *> show diff compute diff-length = byte-length(assertion-expected(assertions-counter)). compute diff-idx = idx - (0.5 * diff-length - 1). if diff-idx < 1 move 1 to diff-idx end-if. if diff-length + diff-idx > byte-length(expected) compute diff-length = byte-length(expected) - diff-idx + 1 end-if. move expected(diff-idx:diff-length) to assertion-expected(assertions-counter). compute diff-length = byte-length(assertion-actual(assertions-counter)). compute diff-idx = idx - (0.5 * diff-length - 1). if diff-idx < 1 move 1 to diff-idx end-if. if diff-length + diff-idx > byte-length(actual) compute diff-length = byte-length(actual) - diff-idx + 1 end-if. move actual(diff-idx:diff-length) to assertion-actual(assertions-counter). end program assert-notequals.