Пример #1
0
    static result_t run(int32_t loglevel)
    {
        if (!s_root)
            return 0;

        if (s_now != s_root)
            return CHECK_ERROR(CALL_E_INVALID_CALL);

        s_now = NULL;

        QuickArray<obj_ptr<_case> > stack;
        QuickArray<std::string> names;
        QuickArray<std::string> msgs;
        int i, j;
        int32_t oldlevel = 0;
        int32_t cnt = 0, errcnt = 0;
        char buf[128];
        date_t da1, da2;

        console_base::get_loglevel(oldlevel);
        console_base::set_loglevel(loglevel);

        stack.append(s_root);

        da1.now();

        while (stack.size())
        {
            _case *p = stack[stack.size() - 1];
            _case *p1, *p2;

            if (p->m_pos == 0)
            {
                for (i = 0; i < (int) p->m_hooks[HOOK_BEFORE].size(); i++)
                    if (v8::Local<v8::Function>::New(isolate,
                                                     p->m_hooks[HOOK_BEFORE][i])->Call(v8::Undefined(isolate),
                                                             0, NULL).IsEmpty())
                    {
                        console_base::set_loglevel(oldlevel);
                        clear();
                        return 0;
                    }
            }

            if (p->m_pos < (int) p->m_subs.size())
            {
                std::string str(stack.size() * 2, ' ');

                p1 = p->m_subs[p->m_pos++];

                if (p1->m_block.IsEmpty())
                {
                    console_base::set_loglevel(oldlevel);
                    if (stack.size() == 1)
                        asyncLog(console_base::_INFO, "");

                    str.append(logger::highLight());
                    str.append(p1->m_name);
                    str.append(COLOR_RESET);

                    asyncLog(console_base::_INFO, str);
                    console_base::set_loglevel(loglevel);

                    stack.append(p1);
                    continue;
                }

                for (j = 0; j < (int) stack.size(); j++)
                {
                    p2 = stack[j];
                    for (i = 0; i < (int) p2->m_hooks[HOOK_BEFORECASE].size();
                            i++)
                        if (v8::Local<v8::Function>::New(isolate,
                                                         p2->m_hooks[HOOK_BEFORECASE][i])->Call(v8::Undefined(isolate),
                                                                 0, NULL).IsEmpty())
                        {
                            console_base::set_loglevel(oldlevel);
                            clear();
                            return 0;
                        }
                }

                cnt++;
                {
                    v8::TryCatch try_catch;
                    date_t d1, d2;

                    d1.now();
                    v8::Local<v8::Function>::New(isolate, p1->m_block)->Call(v8::Undefined(isolate),
                            0, NULL);
                    d2.now();

                    if (try_catch.HasCaught())
                    {
                        sprintf(buf, "%d) ", ++errcnt);

                        p1->m_error = true;
                        if (loglevel > console_base::_ERROR)
                            ReportException(try_catch, 0);
                        else if (loglevel == console_base::_ERROR)
                        {
                            std::string str1(buf);

                            for (i = 1; i < (int)stack.size(); i ++)
                            {
                                str1.append(stack[i]->m_name);
                                str1.append(" ", 1);
                            }
                            str1.append(p1->m_name);
                            names.append(logger::highLight() + str1 + COLOR_RESET);

                            msgs.append(GetException(try_catch, 0));
                        }

                        str.append(buf);
                        str.append(p1->m_name);
                    }
                    else
                    {
                        double n = d2.diff(d1);

                        str.append(logger::notice() + "\xe2\x88\x9a " COLOR_RESET);
                        str.append(p1->m_name);
                        if (n > s_slow / 2)
                        {
                            sprintf(buf, " (%dms) ", (int) n);

                            if (n > s_slow)
                                str.append(logger::error());
                            else
                                str.append(logger::warn());

                            str.append(buf);
                            str.append(COLOR_RESET);
                        }
                    }
                }

                console_base::set_loglevel(oldlevel);
                asyncLog(
                    p1->m_error ?
                    console_base::_ERROR :
                    console_base::_INFO, str);
                console_base::set_loglevel(loglevel);

                for (j = (int) stack.size() - 1; j >= 0; j--)
                {
                    p2 = stack[j];
                    for (i = (int) p2->m_hooks[HOOK_AFTERCASE].size() - 1;
                            i >= 0; i--)
                        if (v8::Local<v8::Function>::New(isolate,
                                                         p2->m_hooks[HOOK_AFTERCASE][i])->Call(v8::Undefined(isolate),
                                                                 0, NULL).IsEmpty())
                        {
                            console_base::set_loglevel(oldlevel);
                            clear();
                            return 0;
                        }
                }
            }

            if (p->m_pos == (int)p->m_subs.size())
            {
                for (i = (int) p->m_hooks[HOOK_AFTER].size() - 1; i >= 0; i--)
                    if (v8::Local<v8::Function>::New(isolate,
                                                     p->m_hooks[HOOK_AFTER][i])->Call(v8::Undefined(isolate),
                                                             0, NULL).IsEmpty())
                    {
                        console_base::set_loglevel(oldlevel);
                        clear();
                        return 0;
                    }
                stack.pop();
            }
        }

        console_base::set_loglevel(oldlevel);
        asyncLog(console_base::_INFO, "");

        if (errcnt == 0)
        {
            da2.now();

            sprintf(buf,
                    (logger::notice() + "  \xe2\x88\x9a %d tests completed" COLOR_RESET " (%dms)").c_str(),
                    cnt, (int) da2.diff(da1));
            asyncLog(console_base::_INFO, buf);
        }
        else
        {
            sprintf(buf, (logger::error() + "  × %d of %d tests failed" COLOR_RESET).c_str(),
                    errcnt, cnt);
            asyncLog(console_base::_ERROR, buf);
        }

        asyncLog(console_base::_INFO, "");

        for (i = 0; i < (int) msgs.size(); i++)
        {
            asyncLog(console_base::_INFO, names[i]);
            asyncLog(console_base::_ERROR, msgs[i]);
        }

        clear();
        return 0;
    }