(List (= scope= flags=0 words=[] bindings=[('DIR', {[ComSub (AndOr OP_AND_IF (Com {[LIT_CHARS cd]} {[DQ [ComSub (Com {[LIT_CHARS dirname]} {[DQ [VarSub BASH_SOURCE bracket_op=(Index {A Atom NODE_ARITH_WORD {[AS_NUM_LITERAL 0]}})]]})]]}) (Com {[LIT_CHARS pwd]}) )]})]) (AndOr OP_OR_IF (Com {[LIT_CHARS source]} {[VarSub DIR] [LIT_CHARS /unittest.bash]}) (List (Com {[LIT_CHARS echo]} {[DQ [LIT_CHARS "Could not source unittest.sh"]]} < (DescriptorRedirectNode target={[LIT_CHARS 2]} &"> 1), > ) (Com {[LIT_CHARS exit]} {[LIT_CHARS 1]}) ) ) (FunctionDef set_up [] (List (= scope= flags=0 words=[] bindings=[('tmp_TEST_TMPDIR', {[VarSub TEST_TMPDIR]})]) (= scope= flags=0 words=[] bindings=[('TEST_TMPDIR', {[VarSub TEST_TMPDIR] [LIT_CHARS /] [VarSub TEST_name]})]) (Com {[LIT_CHARS mkdir]} {[LIT_CHARS -p]} {[VarSub TEST_TMPDIR]}) ) ) (FunctionDef tear_down [] (= scope= flags=0 words=[] bindings=[('TEST_TMPDIR', {[VarSub tmp_TEST_TMPDIR]})]) ) (FunctionDef test_1 [] (Com {[LIT_CHARS echo]} {[DQ [LIT_CHARS "Everything is okay in test_1"]]}) ) (FunctionDef test_2 [] (Com {[LIT_CHARS echo]} {[DQ [LIT_CHARS "Everything is okay in test_2"]]}) ) (FunctionDef test_timestamp [] (List (= scope= flags=0 words=[] bindings=[('ts', {[ComSub (Com {[LIT_CHARS timestamp]})]})]) (AndOr OP_OR_IF (DBracket {B2 BINARY_STRING_TILDE_EQUAL {[VarSub ts]} {[LIT_OTHER "^"] [LIT_OTHER "["] [LIT_CHARS 0-9] [LIT_OTHER "]"] [LIT_LBRACE "{"] [LIT_CHARS 13] [LIT_RBRACE "}"] [LIT_OTHER "$"]}}) (Com {[LIT_CHARS fail]} {[DQ [LIT_CHARS "timestamp wan't valid: "][VarSub ts]]}) ) (= scope= flags=0 words=[] bindings=[('time_diff', {[ComSub (Com {[LIT_CHARS get_run_time]} {[LIT_CHARS 100000]} {[LIT_CHARS 223456]})]})]) (Com {[LIT_CHARS assert_equals]} {[VarSub time_diff]} {[LIT_CHARS 123.456]}) ) ) (FunctionDef test_failure_message [] (List (Com {[LIT_CHARS cd]} {[VarSub TEST_TMPDIR]}) (Com {[LIT_CHARS cat]} < (FilenameRedirectNode filename={[LIT_CHARS thing.sh]} "> 1), (HereDocRedirectNode here_end='EOF' do_expansion=True body_word={[DQ [LIT_CHARS "#!/bin/bash\n"][LIT_CHARS "XML_OUTPUT_FILE="][VarSub TEST_TMPDIR][LIT_CHARS "/dummy.xml\n"][LIT_CHARS "source "][VarSub DIR][LIT_CHARS "/unittest.bash\n"][LIT_CHARS "\n"][LIT_CHARS "function test_thing() {\n"][LIT_CHARS " fail "][RIGHT_D_QUOTE "\""][LIT_CHARS "I'm a failure"][RIGHT_D_QUOTE "\""][LIT_CHARS "\n"][LIT_CHARS "}\n"][LIT_CHARS "\n"][LIT_CHARS "run_suite "][RIGHT_D_QUOTE "\""][LIT_CHARS "thing tests"][RIGHT_D_QUOTE "\""][LIT_CHARS "\n"]]} 0), > ) (Com {[LIT_CHARS chmod]} {[LIT_OTHER "+"] [LIT_CHARS x]} {[LIT_CHARS thing.sh]}) (Fork (Com {[LIT_CHARS ./thing.sh]}) ) (AndOr OP_AND_IF (Com < (FilenameRedirectNode filename={[VarSub TEST_log]} "> 1), > ) (Com {[LIT_CHARS fail]} {[DQ [LIT_CHARS "thing.sh should fail"]]}) ) (Com {[LIT_CHARS expect_not_log]} {[DQ [LIT_CHARS "__fail: No such file or directory"]]}) (Com {[LIT_CHARS assert_contains]} {[DQ [LIT_CHARS "I'm a failure."]]} {[VarSub TEST_TMPDIR] [LIT_CHARS /dummy.xml]}) ) ) (FunctionDef test_no_failure_message [] (List (Com {[LIT_CHARS cd]} {[VarSub TEST_TMPDIR]}) (Com {[LIT_CHARS cat]} < (FilenameRedirectNode filename={[LIT_CHARS thing.sh]} "> 1), (HereDocRedirectNode here_end='EOF' do_expansion=True body_word={[DQ [LIT_CHARS "#!/bin/bash\n"][LIT_CHARS "XML_OUTPUT_FILE="][VarSub TEST_TMPDIR][LIT_CHARS "/dummy.xml\n"][LIT_CHARS "source "][VarSub DIR][LIT_CHARS "/unittest.bash\n"][LIT_CHARS "\n"][LIT_CHARS "function test_thing() {\n"][LIT_CHARS " TEST_passed=blorp\n"][LIT_CHARS "}\n"][LIT_CHARS "\n"][LIT_CHARS "run_suite "][RIGHT_D_QUOTE "\""][LIT_CHARS "thing tests"][RIGHT_D_QUOTE "\""][LIT_CHARS "\n"]]} 0), > ) (Com {[LIT_CHARS chmod]} {[LIT_OTHER "+"] [LIT_CHARS x]} {[LIT_CHARS thing.sh]}) (Fork (Com {[LIT_CHARS ./thing.sh]}) ) (AndOr OP_AND_IF (Com < (FilenameRedirectNode filename={[VarSub TEST_log]} "> 1), > ) (Com {[LIT_CHARS fail]} {[DQ [LIT_CHARS "thing.sh should fail"]]}) ) (Com {[LIT_CHARS expect_not_log]} {[DQ [LIT_CHARS "__fail: No such file or directory"]]}) (Com {[LIT_CHARS assert_contains]} {[DQ [LIT_CHARS "No failure message"]]} {[VarSub TEST_TMPDIR] [LIT_CHARS /dummy.xml]}) ) ) (FunctionDef test_errexit_prints_stack_trace [] (List (Com {[LIT_CHARS cd]} {[VarSub TEST_TMPDIR]}) (Com {[LIT_CHARS cat]} < (FilenameRedirectNode filename={[LIT_CHARS thing.sh]} "> 1), (HereDocRedirectNode here_end='EOF' do_expansion=True body_word={[DQ [LIT_CHARS "#!/bin/bash\n"][LIT_CHARS "XML_OUTPUT_FILE="][VarSub TEST_TMPDIR][LIT_CHARS "/dummy.xml\n"][LIT_CHARS "source "][VarSub DIR][LIT_CHARS "/unittest.bash\n"][LIT_CHARS "\n"][LIT_CHARS "enable_errexit\n"][LIT_CHARS "\n"][LIT_CHARS "function helper() {\n"][LIT_CHARS " echo before\n"][LIT_CHARS " false\n"][LIT_CHARS " echo after\n"][LIT_CHARS "}\n"][LIT_CHARS "\n"][LIT_CHARS "function test_thing() {\n"][LIT_CHARS " helper\n"][LIT_CHARS "}\n"][LIT_CHARS "\n"][LIT_CHARS "run_suite "][RIGHT_D_QUOTE "\""][LIT_CHARS "thing tests"][RIGHT_D_QUOTE "\""][LIT_CHARS "\n"]]} 0), > ) (Com {[LIT_CHARS chmod]} {[LIT_OTHER "+"] [LIT_CHARS x]} {[LIT_CHARS thing.sh]}) (Fork (Com {[LIT_CHARS ./thing.sh]}) ) (AndOr OP_AND_IF (Com < (FilenameRedirectNode filename={[VarSub TEST_log]} "> 1), > ) (Com {[LIT_CHARS fail]} {[DQ [LIT_CHARS "thing.sh should fail"]]}) ) (Com {[LIT_CHARS expect_log]} {[DQ [LIT_CHARS "test_thing FAILED: terminated because this command returned a non-zero status:"]]}) (Com {[LIT_CHARS expect_log]} {[DQ [LIT_CHARS "./thing.sh:[0-9]*: in call to helper"]]}) (Com {[LIT_CHARS expect_log]} {[DQ [LIT_CHARS "./thing.sh:[0-9]*: in call to test_thing"]]}) ) ) (Com {[LIT_CHARS run_suite]} {[DQ [LIT_CHARS "unittests Tests"]]}) )