diff --git a/tap2junit/__main__.py b/tap2junit/__main__.py index 2f30a4d..8250e86 100644 --- a/tap2junit/__main__.py +++ b/tap2junit/__main__.py @@ -43,7 +43,7 @@ def map_yaml_to_junit(test): raw_yaml = f"\n{yamlish.dumps(yaml)}" if yaml else "" err_code = yaml.get("exitcode", 0) err_severity = yaml.get("severity", "") - err_output = yaml.get("stack", "") or raw_yaml + err_output = raw_yaml error_message = yaml.get("message", "") or f"{err_severity} ({err_code})" if err_code < 0 or err_severity == "crashed": t.add_error_info(error_message, err_output, err_code) diff --git a/tap2junit/tap13.py b/tap2junit/tap13.py index 5d6cbe2..8cb4d6a 100644 --- a/tap2junit/tap13.py +++ b/tap2junit/tap13.py @@ -66,8 +66,9 @@ def __init__(self): def _parse_yaml(self, line, in_yaml, in_yaml_block): indentation = len(line) - len(line.lstrip()) if in_yaml_block and indentation > self.tests[-1]._yaml_block_indentation: + self.tests[-1]._yaml_buffer.append(line.rstrip()) return in_yaml, in_yaml_block - elif RE_YAML_BLOCK.match(line): + elif not in_yaml and RE_YAML_BLOCK.match(line): self.tests[-1]._yaml_block_indentation = indentation in_yaml_block = True elif RE_YAMLISH_END.match(line): diff --git a/test/fixtures/test-nested.tap b/test/fixtures/test-nested.tap index d9af80f..9abc19b 100644 --- a/test/fixtures/test-nested.tap +++ b/test/fixtures/test-nested.tap @@ -25,6 +25,8 @@ TAP version 13 code: 'ERR_TEST_FAILURE' stack: |- process.emit (node:events:513:28) + (node:events:51:28) + (node:events:512:28) ... 1..2 not ok 3 - nested diff --git a/test/output/test-nested.xml b/test/output/test-nested.xml index 2d16642..f864031 100644 --- a/test/output/test-nested.xml +++ b/test/output/test-nested.xml @@ -1,6 +1,6 @@ - - + + @@ -11,6 +11,10 @@ code: ERR_TEST_FAILURE duration_ms: 2.332323873 error: Promise resolution is still pending but the event loop has already resolved failureType: cancelledByParent +stack: |- + process.emit (node:events:513:28) + <anonymous> (node:events:51:28) + <anonymous> (node:events:512:28) ... @@ -21,6 +25,7 @@ code: ERR_TEST_FAILURE duration_ms: 2.367870901 error: Promise resolution is still pending but the event loop has already resolved failureType: fail +stack: process.emit (node:events:513:28) ... ['# Subtest: top level 4'] diff --git a/test/output/test.xml b/test/output/test.xml index a55c693..c764660 100644 --- a/test/output/test.xml +++ b/test/output/test.xml @@ -1,6 +1,6 @@ - - + + @@ -939,6 +939,72 @@ duration_ms: 4.339 exitcode: -6 severity: crashed +stack: |- + DebugPrint: 0xe1d05f8a219: [JS_OBJECT_TYPE] + - map: 0x14e5844ec739 <Map(HOLEY_ELEMENTS)> [FastProperties] + - prototype: 0x0e1d05f958c1 <Object map = 0x14e5844e9e51> + - elements: 0x15574d2023b1 <FixedArray[0]> [HOLEY_ELEMENTS] + - properties: 0x15574d2023b1 <FixedArray[0]> { + #_readableState: 0x0e1d05f8a2f9 <ReadableState map = 0x14e5844e7041> (data field 0) + #readable: 0x15574d2029a1 <false> (data field 1) + #_events: 0x0e1d05f8a489 <Object map = 0x14e584483a69> (data field 2) + #_eventsCount: 0 (data field 3) + #_maxListeners: 0x15574d2026f1 <undefined> (data field 4) + #socket: 0x0e1d05f89431 <Socket map = 0x14e5844ebe49> (data field 5) + #connection: 0x0e1d05f89431 <Socket map = 0x14e5844ebe49> (data field 6) + #httpVersionMajor: 1 (data field 7) + #httpVersionMinor: 1 (data field 8) + #httpVersion: 0x0e1d05f8a531 <String[3]: 1.1> (data field 9) + #complete: 0x15574d2028c9 <true> (data field 10) + #headers: 0x0e1d05f8a4a1 <Object map = 0x14e5844eb241> (data field 11) + #rawHeaders: 0x0e1d05f8a0b1 <JSArray[4]> (data field 12) + #trailers: 0x0e1d05f8a4d9 <Object map = 0x14e584482571> (data field 13) + #rawTrailers: 0x0e1d05f8a511 <JSArray[0]> (data field 14) + #aborted: 0x15574d2029a1 <false> (data field 15) + #upgrade: 0x15574d2029a1 <false> (data field 16) + #url: 0x2ba3efe04d69 <String[1]: /> (data field 17) + #method: 0x08828dac8739 <String[3]: GET> (data field 18) + #statusCode: 0x15574d2022b1 <null> (data field 19) + #statusMessage: 0x15574d2022b1 <null> (data field 20) + #client: 0x0e1d05f89431 <Socket map = 0x14e5844ebe49> (data field 21) + #_consuming: 0x15574d2029a1 <false> (data field 22) + #_dumped: 0x15574d2028c9 <true> (data field 23) + } + 0x14e5844ec739: [Map] + - type: JS_OBJECT_TYPE + - instance size: 224 + - inobject properties: 25 + - elements kind: HOLEY_ELEMENTS + - unused property fields: 1 + - enum length: invalid + - back pointer: 0x14e5844ec899 <Map(HOLEY_ELEMENTS)> + - prototype_validity cell: 0x25af6ee37c31 <Cell value= 0> + - instance descriptors #24: 0x0e1d05f870c1 <DescriptorArray[92]> + - layout descriptor: 0 + - transitions #1: 0x14e5844ec8f1 <Map(HOLEY_ELEMENTS)> + #req: (transition to (data field, attrs: [WEC]) @ FATAL ERROR: v8::HandleScope::CreateHandle() Cannot create a handle without a HandleScope + 1: 0x1a151c7 node::DumpBacktrace(_IO_FILE*) [out/Debug/node] + 2: 0x1a523d5 node::Abort() [out/Debug/node] + 3: 0x1a53076 node::FatalError(char const*, char const*) [out/Debug/node] + 4: 0x1df5802 v8::Utils::ReportApiFailure(char const*, char const*) [out/Debug/node] + 5: 0x1de2785 v8::Utils::ApiCheck(bool, char const*, char const*) [out/Debug/node] + 6: 0x24da526 v8::internal::HandleScope::Extend(v8::internal::Isolate*) [out/Debug/node] + 7: 0x1dcc33e v8::internal::HandleScope::CreateHandle(v8::internal::Isolate*, v8::internal::Object*) [out/Debug/node] + 8: 0x1dcc412 v8::internal::HandleScope::GetHandle(v8::internal::Isolate*, v8::internal::Object*) [out/Debug/node] + 9: 0x1dcc05b v8::internal::HandleBase::HandleBase(v8::internal::Object*, v8::internal::Isolate*) [out/Debug/node] + 10: 0x1dde2f5 v8::internal::Handle<v8::internal::Map>::Handle(v8::internal::Map*, v8::internal::Isolate*) [out/Debug/node] + 11: 0x1ef96be v8::internal::Handle<v8::internal::Map> v8::internal::handle<v8::internal::Map>(v8::internal::Map*, v8::internal::Isolate*) [out/Debug/node] + 12: 0x24c01f2 v8::internal::FieldType::AsClass() [out/Debug/node] + 13: 0x24c0435 v8::internal::FieldType::PrintTo(std::ostream&) [out/Debug/node] + 14: 0x27038b8 v8::internal::DescriptorArray::PrintDescriptorDetails(std::ostream&, int, v8::internal::PropertyDetails::PrintMode) [out/Debug/node] + 15: 0x2703c5a v8::internal::TransitionsAccessor::PrintOneTransition(std::ostream&, v8::internal::Name*, v8::internal::Map*) [out/Debug/node] + 16: 0x2703df8 v8::internal::TransitionsAccessor::PrintTransitions(std::ostream&) [out/Debug/node] + 17: 0x26fb22c v8::internal::Map::MapPrint(std::ostream&) [out/Debug/node] + 18: 0x26f827c v8::internal::HeapObject::HeapObjectPrint(std::ostream&) [out/Debug/node] + 19: 0x26f8073 v8::internal::Object::Print(std::ostream&) [out/Debug/node] + 20: 0x29a282f [out/Debug/node] + 21: 0x29a24d1 v8::internal::Runtime_DebugPrint(int, v8::internal::Object**, v8::internal::Isolate*) [out/Debug/node] + 22: 0x3fcb0b31695f ... diff --git a/test/output/test2.xml b/test/output/test2.xml index 50e79ac..3b8d346 100644 --- a/test/output/test2.xml +++ b/test/output/test2.xml @@ -7,6 +7,7 @@ duration_ms: 1.711 exitcode: 1 severity: fail +stack: '' ... diff --git a/test/output/test3.xml b/test/output/test3.xml index 93986f2..f2d09f3 100644 --- a/test/output/test3.xml +++ b/test/output/test3.xml @@ -1,6 +1,6 @@ - - + + @@ -2191,6 +2191,7 @@ duration_ms: 41.541 exitcode: -9 severity: crashed +stack: '' ... diff --git a/test/output/yaml-block.xml b/test/output/yaml-block.xml index 4c30347..951af14 100644 --- a/test/output/yaml-block.xml +++ b/test/output/yaml-block.xml @@ -1,14 +1,434 @@ - - + + --- duration_ms: 4.758 exitcode: 1 severity: fail +stack: |- + TAP version 13 + # Subtest: sync pass todo + ok 1 - sync pass todo # TODO + --- + duration_ms: 0.002648878 ... + ['# Subtest: sync pass todo with message'] + + + + + + + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.000138322 +error: thrown from sync fail todo +failureType: testCodeFailure +stack: |- + Object.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:17:9) + ItTest.runInAsyncScope (node:async_hooks:203:9) + ItTest.run (node:internal/test_runner/test:338:15) + Test.processPendingSubtests (node:internal/test_runner/test:158:27) + ItTest.postRun (node:internal/test_runner/test:390:19) + ItTest.run (node:internal/test_runner/test:352:10) + async Test.processPendingSubtests (node:internal/test_runner/test:158:7) +... + + ['# Subtest: sync fail todo with message'] + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.000129861 +error: thrown from sync fail todo with message +failureType: testCodeFailure +stack: |- + Object.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:21:9) + ItTest.runInAsyncScope (node:async_hooks:203:9) + ItTest.run (node:internal/test_runner/test:338:15) + Test.processPendingSubtests (node:internal/test_runner/test:158:27) + ItTest.postRun (node:internal/test_runner/test:390:19) + ItTest.run (node:internal/test_runner/test:352:10) + Test.processPendingSubtests (node:internal/test_runner/test:158:27) + ItTest.postRun (node:internal/test_runner/test:390:19) + ItTest.run (node:internal/test_runner/test:352:10) + async Test.processPendingSubtests (node:internal/test_runner/test:158:7) +... + + ['# Subtest: sync skip pass'] + + + + + + + + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.000102013 +error: thrown from sync throw fail +failureType: testCodeFailure +stack: |- + Object.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:34:9) + ItTest.runInAsyncScope (node:async_hooks:203:9) + ItTest.run (node:internal/test_runner/test:338:15) + Test.processPendingSubtests (node:internal/test_runner/test:158:27) + ItTest.postRun (node:internal/test_runner/test:390:19) + ItTest.run (node:internal/test_runner/test:352:10) + async Test.processPendingSubtests (node:internal/test_runner/test:158:7) +... + + ['# Subtest: async skip pass'] + + + + + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.000391804 +error: thrown from async throw fail +failureType: testCodeFailure +stack: |- + Object.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:45:9) + ItTest.runInAsyncScope (node:async_hooks:203:9) + ItTest.run (node:internal/test_runner/test:338:15) + Test.processPendingSubtests (node:internal/test_runner/test:158:27) + ItTest.postRun (node:internal/test_runner/test:390:19) + ItTest.run (node:internal/test_runner/test:352:10) + async Test.processPendingSubtests (node:internal/test_runner/test:158:7) +... + + ['# Subtest: async assertion fail'] + + + +--- +code: ERR_ASSERTION +duration_ms: 0.001115182 +error: |- + Expected values to be strictly equal: + + true !== false +failureType: testCodeFailure +stack: |- + Object.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:50:10) + ItTest.runInAsyncScope (node:async_hooks:203:9) + ItTest.run (node:internal/test_runner/test:338:15) + Test.processPendingSubtests (node:internal/test_runner/test:158:27) + ItTest.postRun (node:internal/test_runner/test:390:19) + ItTest.run (node:internal/test_runner/test:352:10) + async Test.processPendingSubtests (node:internal/test_runner/test:158:7) +... + + ['# Subtest: resolve pass'] + + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.000107195 +error: rejected from reject fail +failureType: testCodeFailure +stack: |- + Object.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:58:25) + ItTest.runInAsyncScope (node:async_hooks:203:9) + ItTest.run (node:internal/test_runner/test:338:15) + Test.processPendingSubtests (node:internal/test_runner/test:158:27) + ItTest.postRun (node:internal/test_runner/test:390:19) + ItTest.run (node:internal/test_runner/test:352:10) + async Test.processPendingSubtests (node:internal/test_runner/test:158:7) +... + + ['# Subtest: unhandled rejection - passes but warns'] + + + + + + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.00021773 +error: thrown from subtest sync throw fail +failureType: testCodeFailure +stack: |- + Object.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:91:11) + ItTest.runInAsyncScope (node:async_hooks:203:9) + ItTest.run (node:internal/test_runner/test:338:15) + node:internal/test_runner/test:475:21 + process.processTicksAndRejections (node:internal/process/task_queues:95:5) + async Suite.run (node:internal/test_runner/test:473:5) +... + + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.003179 +error: 1 subtest failed +failureType: subtestsFailed +... + + ['# Subtest: sync throw non-error fail'] + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.000116291 +error: Symbol(thrown symbol from sync throw non-error fail) +failureType: testCodeFailure +... + + ['# Subtest: level 0a', '# Subtest: level 1a'] + + + + + + + + + + + + + + + + + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 7.5765e-05 +error: this should be executed +failureType: testCodeFailure +stack: |- + Object.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:176:9) + ItTest.runInAsyncScope (node:async_hooks:203:9) + ItTest.run (node:internal/test_runner/test:338:15) + Test.processPendingSubtests (node:internal/test_runner/test:158:27) + ItTest.postRun (node:internal/test_runner/test:390:19) + ItTest.run (node:internal/test_runner/test:352:10) + async Test.processPendingSubtests (node:internal/test_runner/test:158:7) +... + + ['# Subtest: <anonymous>'] + + + + + + + + + + + + + + + + + \\\#\\ + + + + + + + + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.000175694 +error: callback failure +failureType: testCodeFailure +stack: |- + Immediate.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:218:10) + process.processImmediate (node:internal/timers:471:21) +... + + ['# Subtest: sync t is this in test'] + + + + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.0001219 +error: passed a callback but also returned a Promise +failureType: callbackAndPromisePresent +... + + ['# Subtest: callback throw'] + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 7.9349e-05 +error: thrown from callback throw +failureType: testCodeFailure +stack: |- + Object.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:240:9) + ItTest.runInAsyncScope (node:async_hooks:203:9) + ItTest.run (node:internal/test_runner/test:325:21) + Test.processPendingSubtests (node:internal/test_runner/test:158:27) + ItTest.postRun (node:internal/test_runner/test:390:19) + ItTest.run (node:internal/test_runner/test:352:10) + async Test.processPendingSubtests (node:internal/test_runner/test:158:7) +... + + ['# Subtest: callback called twice'] + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 8.6067e-05 +error: callback invoked multiple times +failureType: multipleCallbackInvocations +stack: |- + Object.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:245:3) + ItTest.runInAsyncScope (node:async_hooks:203:9) +... + + ['# Subtest: callback called twice in different ticks'] + + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.000366988 +error: callback invoked multiple times +failureType: uncaughtException +stack: process.emit (node:events:513:28) +... + + ['# Subtest: callback async throw'] + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.001866763 +error: thrown from callback async throw +failureType: uncaughtException +stack: process.emit (node:events:513:28) +... + + ['# Subtest: callback async throw after done'] + + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.000247675 +error: customized +failureType: testCodeFailure +... + + ['# Subtest: custom inspect symbol that throws fail'] + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.001367034 +error: |- + { + foo: 1, + [Symbol(nodejs.util.inspect.custom)]: [Function: [nodejs.util.inspect.custom]] + } +failureType: testCodeFailure +... + + ['# Subtest: subtest sync throw fails', '# Subtest: sync throw fails at first'] + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 5.0512e-05 +error: thrown from subtest sync throw fails at first +failureType: testCodeFailure +stack: |- + Object.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:298:11) + ItTest.runInAsyncScope (node:async_hooks:203:9) + ItTest.run (node:internal/test_runner/test:338:15) + node:internal/test_runner/test:475:21 + process.processTicksAndRejections (node:internal/process/task_queues:95:5) + async node:internal/test_runner/test:474:7 + async Suite.run (node:internal/test_runner/test:473:5) +... + + ['# Subtest: sync throw fails at second'] + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 4.8566e-05 +error: thrown from subtest sync throw fails at second +failureType: testCodeFailure +stack: |- + Object.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:301:11) + ItTest.runInAsyncScope (node:async_hooks:203:9) + ItTest.run (node:internal/test_runner/test:338:15) + node:internal/test_runner/test:475:21 + process.processTicksAndRejections (node:internal/process/task_queues:95:5) + async Suite.run (node:internal/test_runner/test:473:5) +... + + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 0.00245857 +error: 2 subtests failed +failureType: subtestsFailed +... + + ['# Subtest: invalid subtest fail'] + + + +--- +code: ERR_TEST_FAILURE +duration_ms: 6.2514e-05 +error: test could not be started because its parent finished +failureType: parentAlreadyFinished +stack: Immediate.<anonymous> (/Users/mosheatlow/repos/node/test/message/test_runner_describe_it.js:161:5) +... + + ['# Warning: Test "unhandled rejection - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from unhandled rejection fail" and would have caused the test to fail, but instead triggered an unhandledRejection event.', '# Warning: Test "async unhandled rejection - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from async unhandled rejection fail" and would have caused the test to fail, but instead triggered an unhandledRejection event.', '# Warning: Test "immediate throw - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from immediate throw fail" and would have caused the test to fail, but instead triggered an uncaughtException event.', '# Warning: Test "immediate reject - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from immediate reject fail" and would have caused the test to fail, but instead triggered an unhandledRejection event.', '# Warning: Test "callback called twice in different ticks" generated asynchronous activity after the test ended. This activity created the error "Error [ERR_TEST_FAILURE]: callback invoked multiple times" and would have caused the test to fail, but instead triggered an uncaughtException event.', '# Warning: Test "callback async throw after done" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event.', '# tests 54', '# pass 23', '# fail 17', '# cancelled 0', '# skipped 9', '# todo 5', '# duration_ms 4.566779807']