Fix #739 (test failures).

Use JSON in debug serializer output unless it fails due to e.g. cyclic
values, in which case use toSource.
Disable file stats code by default, since its output isn't used.

This was SVN commit r8975.
This commit is contained in:
Ykkrosh 2011-02-24 00:32:38 +00:00
parent 059a53dd37
commit f6c1d98c9a
9 changed files with 107 additions and 19 deletions

View file

@ -31,6 +31,7 @@
#include "lib/timer.h"
#if FILE_STATS_ENABLED
// vfs
static size_t vfs_files;
@ -342,3 +343,5 @@ void file_stats_dump()
(unsigned long)ab_connection_attempts, (unsigned long)ab_repeated_connections, (unsigned long)(ab_connection_attempts-ab_repeated_connections)
);
}
#endif // FILE_STATS_ENABLED

View file

@ -27,7 +27,7 @@
#ifndef INCLUDED_FILE_STATS
#define INCLUDED_FILE_STATS
#define FILE_STATS_ENABLED 1
#define FILE_STATS_ENABLED 0
enum FileIOImplentation { FI_LOWIO, FI_AIO, FI_BCACHE, FI_MAX_IDX };
@ -106,7 +106,7 @@ class ScopedIoMonitor
public:
ScopedIoMonitor() {}
~ScopedIoMonitor() {}
void NotifyOfSuccess(FileIOImplentation fi, wchar_t mode, off_t size) {}
void NotifyOfSuccess(FileIOImplentation UNUSED(fi), wchar_t UNUSED(mode), off_t UNUSED(size)) {}
};
#define stats_io_check_seek(blockId)
#define stats_cb_start()

View file

@ -88,7 +88,9 @@ VfsFile* VfsDirectory::AddFile(const VfsFile& file)
previousFile = newFile;
}
else
{
stats_vfs_file_add(file.Size());
}
return &(*ret.first).second;
}

View file

@ -263,6 +263,8 @@ void ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report)
jsval excn;
if (JS_GetPendingException(cx, &excn) && JSVAL_IS_OBJECT(excn))
{
// TODO: this violates the docs ("The error reporter callback must not reenter the JSAPI.")
jsval rval;
const char dumpStack[] = "this.stack.trimRight().replace(/^/mg, ' ')"; // indent each line
if (JS_EvaluateScript(cx, JSVAL_TO_OBJECT(excn), dumpStack, ARRAY_SIZE(dumpStack)-1, "(eval)", 1, &rval))
@ -794,15 +796,6 @@ bool ScriptInterface::Eval_(const wchar_t* code, jsval& rval)
return ok ? true : false;
}
std::wstring ScriptInterface::ToString(jsval obj)
{
if (JSVAL_IS_VOID(obj))
return L"(void 0)";
std::wstring source = L"(error)";
CallFunction(obj, "toSource", source);
return source;
}
CScriptValRooted ScriptInterface::ParseJSON(const std::string& string_utf8)
{
std::wstring attrsW = wstring_from_utf8(string_utf8);
@ -869,6 +862,18 @@ struct Stringifier
std::stringstream stream;
};
struct StringifierW
{
static JSBool callback(const jschar* buf, uint32 len, void* data)
{
utf16string str(buf, buf+len);
static_cast<StringifierW*>(data)->stream << std::wstring(str.begin(), str.end());
return JS_TRUE;
}
std::wstringstream stream;
};
std::string ScriptInterface::StringifyJSON(jsval obj, bool indent)
{
Stringifier str;
@ -881,6 +886,40 @@ std::string ScriptInterface::StringifyJSON(jsval obj, bool indent)
return str.stream.str();
}
std::wstring ScriptInterface::ToString(jsval obj, bool pretty)
{
if (JSVAL_IS_VOID(obj))
return L"(void 0)";
// Try to stringify as JSON if possible
// (TODO: this is maybe a bad idea since it'll drop 'undefined' values silently)
if (pretty)
{
StringifierW str;
// Temporary disable the error reporter, so we don't print complaints about cyclic values
JSErrorReporter er = JS_SetErrorReporter(m->m_cx, NULL);
bool ok = JS_Stringify(m->m_cx, &obj, NULL, INT_TO_JSVAL(2), &StringifierW::callback, &str);
// Restore error reporter
JS_SetErrorReporter(m->m_cx, er);
if (ok)
return str.stream.str();
// Clear the exception set when Stringify failed
JS_ClearPendingException(m->m_cx);
}
// Caller didn't want pretty output, or JSON conversion failed (e.g. due to cycles),
// so fall back to obj.toSource()
std::wstring source = L"(error)";
CallFunction(obj, "toSource", source);
return source;
}
void ScriptInterface::ReportError(const char* msg)
{
// JS_ReportError by itself doesn't seem to set a JS-style exception, and so

View file

@ -200,7 +200,7 @@ public:
template<typename T, typename CHAR> bool Eval(const CHAR* code, T& out);
std::wstring ToString(jsval obj);
std::wstring ToString(jsval obj, bool pretty = false);
/**
* Parse a UTF-8-encoded JSON string. Returns the undefined value on error.

View file

@ -149,9 +149,9 @@ void CDebugSerializer::PutString(const char* name, const std::string& value)
void CDebugSerializer::PutScriptVal(const char* name, jsval value)
{
std::string source = m_ScriptInterface.StringifyJSON(value, true);
std::wstring source = m_ScriptInterface.ToString(value, true);
m_Stream << INDENT << name << ": " << source << "\n";
m_Stream << INDENT << name << ": " << utf8_from_wstring(source) << "\n";
}
void CDebugSerializer::PutRaw(const char* name, const u8* data, size_t len)

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2010 Wildfire Games.
/* Copyright (C) 2011 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -660,11 +660,26 @@ public:
"entities:\n"
"- id: 1\n"
" TestScript1_values:\n"
" object: ({x:1234, str:\"this is a string\", things:{a:1, b:\"2\", c:[3, \"4\", [5, []]]}})\n"
" object: {\n"
" \"x\": 1234,\n"
" \"str\": \"this is a string\",\n"
" \"things\": {\n"
" \"a\": 1,\n"
" \"b\": \"2\",\n"
" \"c\": [\n"
" 3,\n"
" \"4\",\n"
" [\n"
" 5,\n"
" []\n"
" ]\n"
" ]\n"
" }\n"
"}\n"
"\n"
"- id: 2\n"
" TestScript1_entity:\n"
" object: ({})\n"
" object: {}\n"
"\n"
"- id: 3\n"
" TestScript1_nontree:\n"
@ -672,7 +687,9 @@ public:
"\n"
"- id: 4\n"
" TestScript1_custom:\n"
" object: ({c:1})\n"
" object: {\n"
" \"c\": 1\n"
"}\n"
"\n"
);

View file

@ -273,7 +273,20 @@ public:
std::stringstream stream;
CDebugSerializer serialize(script, stream);
serialize.ScriptVal("script", obj);
TS_ASSERT_STR_EQUALS(stream.str(), "script: ({x:123, y:[1, 1.5, \"2\", \"test\", (void 0), null, true, false]})\n");
TS_ASSERT_STR_EQUALS(stream.str(),
"script: {\n"
" \"x\": 123,\n"
" \"y\": [\n"
" 1,\n"
" 1.5,\n"
" \"2\",\n"
" \"test\",\n"
" null,\n"
" null,\n"
" true,\n"
" false\n"
" ]\n"
"}\n");
}
{

View file

@ -33,6 +33,7 @@
#include "lib/sysdep/os/win/wdbg_heap.h"
#endif
#include "lib/timer.h"
#include "lib/sysdep/sysdep.h"
#include "scriptinterface/ScriptInterface.h"
@ -64,7 +65,20 @@ class LeakReporter : public CxxTest::GlobalFixture
};
class TimerSetup : public CxxTest::GlobalFixture
{
virtual bool setUpWorld()
{
// Timer must be initialised, else things will break when tests do IO
timer_LatchStartTime();
return true;
}
};
static LeakReporter leakReporter;
static TimerSetup timerSetup;
// Definition of functions from lib/self_test.h