XS-libboost-mini

 view release on metacpan or  search on metacpan

include/boost/test/impl/junit_log_formatter.ipp  view on Meta::CPAN


    return filename;

}

// ************************************************************************** //
// **************               junit_log_formatter              ************** //
// ************************************************************************** //

void
junit_log_formatter::log_start( std::ostream& /*ostr*/, counter_t /*test_cases_amount*/)
{
    map_tests.clear();
    list_path_to_root.clear();
    runner_log_entry.clear();
}

//____________________________________________________________________________//

class junit_result_helper : public test_tree_visitor {
private:
    typedef junit_impl::junit_log_helper::assertion_entry assertion_entry;
    typedef std::vector< assertion_entry >::const_iterator vect_assertion_entry_citerator;
    typedef std::list<std::string>::const_iterator list_str_citerator;

public:
    explicit junit_result_helper(
        std::ostream& stream,
        test_unit const& ts,
        junit_log_formatter::map_trace_t const& mt,
        junit_impl::junit_log_helper const& runner_log_,
        bool display_build_info )
    : m_stream(stream)
    , m_ts( ts )
    , m_map_test( mt )
    , runner_log( runner_log_ )
    , m_id( 0 )
    , m_display_build_info(display_build_info)
    { }

    void add_log_entry(assertion_entry const& log) const
    {
        std::string entry_type;
        if( log.log_entry == assertion_entry::log_entry_failure ) {
            entry_type = "failure";
        }
        else if( log.log_entry == assertion_entry::log_entry_error ) {
            entry_type = "error";
        }
        else {
            return;
        }

        m_stream
            << "<" << entry_type
            << " message" << utils::attr_value() << log.logentry_message
            << " type" << utils::attr_value() << log.logentry_type
            << ">";

        if(!log.output.empty()) {
            m_stream << utils::cdata() << "\n" + log.output;
        }

        m_stream << "</" << entry_type << ">";
    }

    struct conditional_cdata_helper {
        std::ostream &ostr;
        std::string const field;
        bool empty;

        conditional_cdata_helper(std::ostream &ostr_, std::string field_)
        : ostr(ostr_)
        , field(field_)
        , empty(true)
        {}

        ~conditional_cdata_helper() {
            if(!empty) {
                ostr << BOOST_TEST_L( "]]>" ) << "</" << field << '>' << std::endl;
            }
        }

        void operator()(const std::string& s) {
            bool current_empty = s.empty();
            if(empty) {
                if(!current_empty) {
                    empty = false;
                    ostr << '<' << field << '>' << BOOST_TEST_L( "<![CDATA[" );
                }
            }
            if(!current_empty) {
                ostr << s;
            }
        }
    };

    std::list<std::string> build_skipping_chain(test_unit const & tu) const
    {
        // we enter here because we know that the tu has been skipped.
        // either junit has not seen this tu, or it is indicated as disabled
        assert(m_map_test.count(tu.p_id) == 0 || results_collector.results( tu.p_id ).p_skipped);

        std::list<std::string> out;

        test_unit_id id(tu.p_id);
        while( id != m_ts.p_id && id != INV_TEST_UNIT_ID) {
            test_unit const& tu_hierarchy = boost::unit_test::framework::get( id, TUT_ANY );
            out.push_back("- disabled test unit: '" + tu_name_remove_newlines(tu_hierarchy.full_name()) + "'\n");
            if(m_map_test.count(id) > 0)
            {
                // junit has seen the reason: this is enough for constructing the chain
                break;
            }
            id = tu_hierarchy.p_parent_id;
        }
        junit_log_formatter::map_trace_t::const_iterator it_element_stack(m_map_test.find(id));
        if( it_element_stack != m_map_test.end() )
        {
            out.push_back("- reason: '" + it_element_stack->second.skipping_reason + "'");
            out.push_front("Test case disabled because of the following chain of decision:\n");
        }

        return out;
    }

    std::string get_class_name(test_unit const & tu_class) const {
        std::string classname;
        test_unit_id id(tu_class.p_parent_id);
        while( id != m_ts.p_id && id != INV_TEST_UNIT_ID ) {
            test_unit const& tu = boost::unit_test::framework::get( id, TUT_ANY );
            classname = tu_name_normalize(tu.p_name) + "." + classname;
            id = tu.p_parent_id;
        }

        // removes the trailing dot
        if(!classname.empty() && *classname.rbegin() == '.') {
            classname.erase(classname.size()-1);
        }

        return classname;
    }

    void    write_testcase_header(test_unit const & tu,
                                  test_results const *tr,
                                  int nb_assertions) const
    {
        std::string name;
        std::string classname;

        if(tu.p_id == m_ts.p_id ) {
            name = "boost_test";
        }
        else {
            classname = get_class_name(tu);
            name = tu_name_normalize(tu.p_name);
        }

        if( tu.p_type == TUT_SUITE ) {
            if(tr->p_timed_out)
              name += "-timed-execution";
            else
              name += "-setup-teardown";
        }

        m_stream << "<testcase assertions" << utils::attr_value() << nb_assertions;
        if(!classname.empty())
            m_stream << " classname" << utils::attr_value() << classname;

        // test case name and time taken
        m_stream
            << " name"      << utils::attr_value() << name
            << " time"      << utils::attr_value() << double(tr->p_duration_microseconds) * 1E-6
            << ">" << std::endl;
    }

    void    write_testcase_system_out(junit_impl::junit_log_helper const &detailed_log,
                                      test_unit const * tu,
                                      bool skipped) const
    {
        // system-out + all info/messages, the object skips the empty entries
        conditional_cdata_helper system_out_helper(m_stream, "system-out");

        // indicate why the test has been skipped first
        if( skipped ) {
            std::list<std::string> skipping_decision_chain = build_skipping_chain(*tu);
            for(list_str_citerator it(skipping_decision_chain.begin()), ite(skipping_decision_chain.end());
                it != ite;
                ++it)
            {
              system_out_helper(*it);
            }
        }

        // stdout
        for(list_str_citerator it(detailed_log.system_out.begin()), ite(detailed_log.system_out.end());
            it != ite;
            ++it)
        {
          system_out_helper(*it);
        }

        // warning/info message last
        for(vect_assertion_entry_citerator it(detailed_log.assertion_entries.begin());
            it != detailed_log.assertion_entries.end();
            ++it)
        {
            if(it->log_entry != assertion_entry::log_entry_info)
                continue;
            system_out_helper(it->output);
        }
    }

    void    write_testcase_system_err(junit_impl::junit_log_helper const &detailed_log,
                                      test_unit const * tu,
                                      test_results const *tr) const
    {
        // system-err output + test case informations
        bool has_failed = (tr != 0) ? !tr->p_skipped && !tr->passed() : false;
        if(!detailed_log.system_err.empty() || has_failed)
        {
            std::ostringstream o;
            if(has_failed) {
                o << "Failures detected in:" << std::endl;
            }
            else {
                o << "ERROR STREAM:" << std::endl;
            }

            if(tu->p_type == TUT_SUITE) {
                if( tu->p_id == m_ts.p_id ) {
                    o << " boost.test global setup/teardown" << std::endl;
                } else {
                    o << "- test suite: " << tu_name_remove_newlines(tu->full_name()) << std::endl;
                }
            }
            else {
              o << "- test case: " << tu_name_remove_newlines(tu->full_name());
              if(!tu->p_description.value.empty())
                  o << " '" << tu->p_description << "'";

              o << std::endl
                  << "- file: " << file_basename(tu->p_file_name) << std::endl
                  << "- line: " << tu->p_line_num << std::endl
                  ;
            }

            if(!detailed_log.system_err.empty())
                o << std::endl << "STDERR BEGIN: ------------" << std::endl;

            for(list_str_citerator it(detailed_log.system_err.begin()), ite(detailed_log.system_err.end());
                it != ite;
                ++it)
            {
              o << *it;
            }

            if(!detailed_log.system_err.empty())
                o << std::endl << "STDERR END    ------------" << std::endl;

            conditional_cdata_helper system_err_helper(m_stream, "system-err");
            system_err_helper(o.str());
        }
    }

    int     get_nb_assertions(junit_impl::junit_log_helper const &detailed_log,
                              test_unit const & tu,
                              test_results const *tr) const {
        int nb_assertions(-1);
        if( tu.p_type == TUT_SUITE ) {
            nb_assertions = 0;
            for(vect_assertion_entry_citerator it(detailed_log.assertion_entries.begin());
                it != detailed_log.assertion_entries.end();
                ++it)
            {
                if(it->log_entry != assertion_entry::log_entry_info)
                    nb_assertions++;
            }
        }
        else {
            nb_assertions = static_cast<int>(tr->p_assertions_passed + tr->p_assertions_failed);
        }

        return nb_assertions;
    }

    void    output_detailed_logs(junit_impl::junit_log_helper const &detailed_log,
                                 test_unit const & tu,
                                 bool skipped,
                                 test_results const *tr) const
    {
        int nb_assertions = get_nb_assertions(detailed_log, tu, tr);
        if(!nb_assertions && tu.p_type == TUT_SUITE)
            return;

        write_testcase_header(tu, tr, nb_assertions);

        if( skipped ) {
            m_stream << "<skipped/>" << std::endl;
        }
        else {

          for(vect_assertion_entry_citerator it(detailed_log.assertion_entries.begin());
              it != detailed_log.assertion_entries.end();
              ++it)
          {
              add_log_entry(*it);
          }
        }

        write_testcase_system_out(detailed_log, &tu, skipped);
        write_testcase_system_err(detailed_log, &tu, tr);
        m_stream << "</testcase>" << std::endl;
    }

    void    visit( test_case const& tc ) BOOST_OVERRIDE
    {

        test_results const& tr = results_collector.results( tc.p_id );
        junit_log_formatter::map_trace_t::const_iterator it_find = m_map_test.find(tc.p_id);
        if(it_find == m_map_test.end())



( run in 5.290 seconds using v1.01-cache-2.11-cpan-140bd7fdf52 )