@@ -13,6 +13,7 @@ function set_up() {
1313 _BASHUNIT_REPORTS_TEST_STATUSES=()
1414 _BASHUNIT_REPORTS_TEST_DURATIONS=()
1515 _BASHUNIT_REPORTS_TEST_ASSERTIONS=()
16+ _BASHUNIT_REPORTS_TEST_FAILURES=()
1617
1718 # Unset report env vars by default
1819 unset BASHUNIT_LOG_JUNIT
@@ -92,9 +93,10 @@ function test_add_test_passed_sets_passed_status() {
9293function test_add_test_failed_sets_failed_status() {
9394 BASHUNIT_LOG_JUNIT=" report.xml"
9495
95- bashunit::reports::add_test_failed " test.sh" " my_test" " 100" " 2"
96+ bashunit::reports::add_test_failed " test.sh" " my_test" " 100" " 2" " some error "
9697
9798 assert_same " failed" " ${_BASHUNIT_REPORTS_TEST_STATUSES[0]} "
99+ assert_same " some error" " ${_BASHUNIT_REPORTS_TEST_FAILURES[0]} "
98100}
99101
100102# === Core add_test tests ===
@@ -118,13 +120,14 @@ function test_add_test_tracks_when_html_report_enabled() {
118120function test_add_test_populates_all_arrays() {
119121 BASHUNIT_LOG_JUNIT=" report.xml"
120122
121- bashunit::reports::add_test " my_file.sh" " my_test_name" " 250" " 5" " failed"
123+ bashunit::reports::add_test " my_file.sh" " my_test_name" " 250" " 5" " failed" " expected X got Y "
122124
123125 assert_same " my_file.sh" " ${_BASHUNIT_REPORTS_TEST_FILES[0]} "
124126 assert_same " my_test_name" " ${_BASHUNIT_REPORTS_TEST_NAMES[0]} "
125127 assert_same " failed" " ${_BASHUNIT_REPORTS_TEST_STATUSES[0]} "
126128 assert_same " 250" " ${_BASHUNIT_REPORTS_TEST_DURATIONS[0]} "
127129 assert_same " 5" " ${_BASHUNIT_REPORTS_TEST_ASSERTIONS[0]} "
130+ assert_same " expected X got Y" " ${_BASHUNIT_REPORTS_TEST_FAILURES[0]} "
128131}
129132
130133# === JUnit XML generation tests ===
@@ -156,9 +159,10 @@ function test_generate_junit_xml_includes_testsuite_attributes() {
156159
157160 assert_contains ' <testsuite name="bashunit"' " $content "
158161 assert_contains ' tests="1"' " $content "
159- assert_contains ' passed="5"' " $content "
160162 assert_contains ' failures="1"' " $content "
161- assert_contains ' time="1234"' " $content "
163+ assert_contains ' skipped="3"' " $content "
164+ assert_contains ' errors="0"' " $content "
165+ assert_contains ' time="1.234"' " $content "
162166}
163167
164168function test_generate_junit_xml_includes_testcase_elements() {
@@ -173,9 +177,82 @@ function test_generate_junit_xml_includes_testcase_elements() {
173177
174178 assert_contains ' <testcase file="my_test.sh"' " $content "
175179 assert_contains ' name="test_example"' " $content "
176- assert_contains ' status="passed"' " $content "
177- assert_contains ' assertions="3"' " $content "
178- assert_contains ' time="500"' " $content "
180+ assert_contains ' time="0.500"' " $content "
181+ assert_not_contains ' status=' " $content "
182+ assert_not_contains ' assertions=' " $content "
183+ }
184+
185+ function test_generate_junit_xml_passed_has_no_children() {
186+ _mock_state_functions
187+ BASHUNIT_LOG_JUNIT=" report.xml"
188+
189+ bashunit::reports::add_test " test.sh" " test_ok" " 200" " 1" " passed"
190+ bashunit::reports::generate_junit_xml " $_TEMP_OUTPUT_FILE "
191+
192+ local content
193+ content=$( cat " $_TEMP_OUTPUT_FILE " )
194+
195+ assert_not_contains ' <failure' " $content "
196+ assert_not_contains ' <skipped' " $content "
197+ }
198+
199+ function test_generate_junit_xml_skipped_testcase() {
200+ _mock_state_functions
201+ BASHUNIT_LOG_JUNIT=" report.xml"
202+
203+ bashunit::reports::add_test " test.sh" " test_skip" " 0" " 0" " skipped"
204+ bashunit::reports::generate_junit_xml " $_TEMP_OUTPUT_FILE "
205+
206+ local content
207+ content=$( cat " $_TEMP_OUTPUT_FILE " )
208+
209+ assert_contains ' <skipped/>' " $content "
210+ assert_not_contains ' <failure' " $content "
211+ }
212+
213+ function test_generate_junit_xml_incomplete_testcase() {
214+ _mock_state_functions
215+ BASHUNIT_LOG_JUNIT=" report.xml"
216+
217+ bashunit::reports::add_test " test.sh" " test_todo" " 0" " 0" " incomplete"
218+ bashunit::reports::generate_junit_xml " $_TEMP_OUTPUT_FILE "
219+
220+ local content
221+ content=$( cat " $_TEMP_OUTPUT_FILE " )
222+
223+ assert_contains ' <skipped message="Test incomplete"/>' " $content "
224+ assert_not_contains ' <failure' " $content "
225+ }
226+
227+ function test_generate_junit_xml_failure_element_without_type() {
228+ _mock_state_functions
229+ BASHUNIT_LOG_JUNIT=" report.xml"
230+
231+ local failure_msg=" Assertion failed: expected 42 but got 0"
232+ bashunit::reports::add_test " test_fail.sh" " test_failure" " 1000" " 5" " failed" " $failure_msg "
233+ bashunit::reports::generate_junit_xml " $_TEMP_OUTPUT_FILE "
234+
235+ local content
236+ content=$( cat " $_TEMP_OUTPUT_FILE " )
237+
238+ assert_contains ' <failure message="Test failed">' " $content "
239+ assert_contains " $failure_msg </failure>" " $content "
240+ assert_not_contains ' type=' " $content "
241+ }
242+
243+ function test_generate_junit_xml_failure_element_with_xml_escaping() {
244+ _mock_state_functions
245+ BASHUNIT_LOG_JUNIT=" report.xml"
246+
247+ local failure_msg=' Expected "value1" & "value2" to be > other'
248+ bashunit::reports::add_test " test_fail.sh" " test_xml_escape" " 500" " 2" " failed" " $failure_msg "
249+ bashunit::reports::generate_junit_xml " $_TEMP_OUTPUT_FILE "
250+
251+ local content
252+ content=$( cat " $_TEMP_OUTPUT_FILE " )
253+
254+ # Verify XML escaping is applied
255+ assert_contains ' Expected "value1" & "value2" to be > other</failure>' " $content "
179256}
180257
181258# === HTML report generation tests ===
0 commit comments