15 #ifndef INCG_IRIS_IUTEST_SSTP_NOTIFIER_HPP_1187A63F_E99B_4289_A562_3C87B9739B7D_ 
   16 #define INCG_IRIS_IUTEST_SSTP_NOTIFIER_HPP_1187A63F_E99B_4289_A562_3C87B9739B7D_ 
   20 #include "../iutest_core.hpp" 
   22 #if IUTEST_HAS_STREAM_RESULT 
   23 #include "../internal/iutest_socket.hpp" 
   25 #ifndef IUTEST_SSTPNOTIFIER_JAPANESE 
   26 #  define IUTEST_SSTPNOTIFIER_JAPANESE  1 
   40 class SSTP : 
public Socket
 
   53           OPTION_NODESCRIPT = 0x0001
 
   54         , OPTION_NOTRANSLATE= 0x0002
 
   56     static const int DEFAULT_PORT=9801;
 
   62         ::std::string m_message;
 
   68         explicit Response(
const char (&str)[N])
 
   69             : m_major(0), m_minor(0), m_code(0)
 
   75         bool Parse(
const char (&str)[N])
 
   78             if( !detail::IsStringForwardMatching(str, 
"SSTP/") ) {
 
   82             m_major = strtol(str+5, &p, 10);
 
   83             m_minor = strtol(p+1, &p, 10);
 
   84             m_code = strtol(p+1, &p, 10);
 
   90     explicit SSTP(const ::std::string& sender, eCharset charset=CHARSET_SHIFTJIS)
 
   91         : m_Sender(sender), m_Charset(charset), m_bInitialOpen(false) {}
 
   94     bool Open(
const char* host, 
const char* port)
 
   98         m_bInitialOpen = Socket::Open(host, port);
 
   99         return m_bInitialOpen;
 
  104         if( m_bInitialOpen && Socket::Open(m_Host.c_str(), m_Port.c_str()) )
 
  106             SendLn(
"NOTIFY SSTP/1.1");
 
  107             SendLn(
"Sender: " + m_Sender);
 
  108             SendLn(
"Charset: " + FormatCharset(m_Charset));
 
  120     SSTP& Event(const ::std::string& 
id)
 
  122         SendLn(
"Event: " + 
id);
 
  125     SSTP& Reference(
int index, const ::std::string& info)
 
  127         SendLn(
"Reference" + StreamableToString(index) + 
": " + info);
 
  130     SSTP& Script(const ::std::string& script)
 
  132         SendLn(
"Script: " + MultiByteStringToUTF8(script.c_str()));
 
  135     SSTP& Option(eOption option)
 
  137         SendLn(
"Option: " + FormatOption(option));
 
  140     SSTP& Locale(const ::std::string& locale)
 
  142         SendLn(
"Locale: " + locale);
 
  145     SSTP& Marker(const ::std::string& maker)
 
  147         SendLn(
"Marker: " + maker);
 
  150     SSTP& Entry(const ::std::string& entry)
 
  152         SendLn(
"Entry: " + entry);
 
  157         SendLn(
"HWnd: " + StreamableToString(hWnd));
 
  160     SSTP& IfGhost(const ::std::string& ghost)
 
  162         SendLn(
"IfGhost: " + ghost);
 
  169         if( Read(buf, 
sizeof(buf)) )
 
  171 #if defined(_IUTEST_DEBUG) 
  175             if( res.m_code < 200 || res.m_code >= 300 )
 
  182     ::std::string FormatCharset(eCharset charset)
 
  189         case CHARSET_SHIFTJIS:
 
  191         case CHARSET_ISO_220_JP:
 
  192             return "ISO-2022-JP";
 
  199     ::std::string FormatOption(eOption option)
 
  201         ::std::string str=
"";
 
  202         if( option & OPTION_NODESCRIPT )
 
  206         if( option & OPTION_NOTRANSLATE )
 
  212             str += 
"notranslate";
 
  217     ::std::string m_Sender;
 
  218     ::std::string m_Host;
 
  219     ::std::string m_Port;
 
  236     explicit SakuraScript(
const char* script) : m_script(script) {}
 
  237     explicit SakuraScript(const ::std::string& script) : m_script(script) {}
 
  239     SakuraScript& Append(const ::std::string& str)
 
  241         m_script.append(str);
 
  245     SakuraScript& Append(
const T& v)
 
  247         m_script.append(StreamableToString(v));
 
  252     SakuraScript& Surface(
int id) { Append(
"\\s[" + StreamableToString(
id) + 
"]"); 
return *
this; }
 
  253     SakuraScript& Animate(
int id) { Append(
"\\i[" + StreamableToString(
id) + 
"]"); 
return *
this; }
 
  254     SakuraScript& 
Concat() { m_script.insert(0, 
"\\C"); 
return *
this; }
 
  255     SakuraScript& Ln() { Append(
"\\n"); 
return *
this; }
 
  256     SakuraScript& Home() { Append(
"\\h"); 
return *
this; }
 
  257     SakuraScript& You() { Append(
"\\u"); 
return *
this; }
 
  258     SakuraScript& Scope(
int id) { Append(
"\\p[" + StreamableToString(
id) + 
"]"); 
return *
this; }
 
  259     SakuraScript& Quick() { Append(
"\\_q"); 
return *
this; }
 
  261     SakuraScript& Open(const ::std::string& file) { Append(
"\\![open,file," + file + 
"]"); 
return *
this; }
 
  264     const ::std::string& ToString()
 
  267         detail::StringReplace(m_script, 
'\n', 
"\\n");
 
  272     SakuraScript& operator + (const ::std::string& str)
 
  277     SakuraScript& operator + (
const T& v)
 
  283     ::std::string m_script;
 
  305         , AngerToCoverEmbarrassment 
 
  353 class SSTPNotifier : 
public EmptyTestEventListener
 
  355     typedef ukagaka::SakuraScript   Script;
 
  356     typedef ukagaka::ghost::Emily4  Ghost;
 
  358     explicit SSTPNotifier(
const char* host, 
int port=detail::SSTP::DEFAULT_PORT);
 
  362     virtual void OnTestIterationStart(
const UnitTest& test
 
  370     virtual void OnTestIterationEnd(
const UnitTest& test
 
  375     ::std::string FormatMessage(const ::std::string& path);
 
  376     ::std::string FormatPath(const ::std::string& path);
 
  377     ::std::string FormatBool(
bool b);
 
  387     static TestEventListener* SetUp(
const char* host, 
int port=detail::SSTP::DEFAULT_PORT)
 
  390         TestEventListener* p = 
new SSTPNotifier(host, port);
 
  401 IUTEST_IPP_INLINE SSTPNotifier::SSTPNotifier(
const char* host, 
int port)
 
  402     : m_sstp(
"iutest", detail::SSTP::CHARSET_UTF8)
 
  404     if( !m_sstp.Open(host, StreamableToString(port).c_str()) )
 
  406         IUTEST_LOG_(WARNING) << 
"SSTPNotifier: failed connect to " << host << 
":" << port;
 
  411 IUTEST_IPP_INLINE 
void SSTPNotifier::OnTestProgramStart(
const UnitTest& test)
 
  413     IUTEST_UNUSED_VAR(test);
 
  415 #if IUTEST_SSTPNOTIFIER_JAPANESE 
  416         .Script(Script(
"テストスタ~ト").Ln().ToString())
 
  418         .Script(Script(
"Start test.").Ln().ToString())
 
  422 IUTEST_IPP_INLINE 
void SSTPNotifier::OnTestIterationStart(
const UnitTest& test
 
  425     IUTEST_UNUSED_VAR(test);
 
  427 #if IUTEST_SSTPNOTIFIER_JAPANESE 
  428         .Script(Script(StreamableToString(iteration + 1) + 
"回目のテストだよ").
Concat().Ln().ToString())
 
  430         .Script(Script(StreamableToString(iteration+1) + 
"-th test.").
Concat().Ln().ToString())
 
  434 IUTEST_IPP_INLINE 
void SSTPNotifier::OnTestCaseStart(
const TestCase& test_case)
 
  437         .Script(Script().Surface(Ghost::Normal)
 
  438 #
if IUTEST_SSTPNOTIFIER_JAPANESE
 
  439             .Append(StreamableToString(test_case.name()) + 
" テストケースを開始").Concat().Ln().ToString())
 
  441             .Append(StreamableToString(test_case.name()) + 
" Start TestCase...").Concat().Ln().ToString())
 
  445 IUTEST_IPP_INLINE 
void SSTPNotifier::OnTestStart(
const TestInfo& test_info)
 
  448         .Script(Script().Surface(Ghost::Normal)
 
  449 #
if IUTEST_SSTPNOTIFIER_JAPANESE
 
  450             .Append(StreamableToString(test_info.name()) + 
" テストを開始").Concat().Ln().ToString())
 
  452             .Append(StreamableToString(test_info.name()) + 
" Start Test...").Concat().Ln().ToString())
 
  456 IUTEST_IPP_INLINE 
void SSTPNotifier::OnTestPartResult(
const TestPartResult& test_part_result)
 
  458     const char* filename = test_part_result.file_name();
 
  459     if( filename == NULL )
 
  464     if( test_part_result.passed() )
 
  470             .Script(Script().Surface(Ghost::Anxiety).Append(FormatPath(filename)
 
  471 #
if IUTEST_SSTPNOTIFIER_JAPANESE
 
  472                 + 
"の" + StreamableToString(test_part_result.line_number()) + 
"行目で失敗したよ\n" 
  474                 + 
": " + StreamableToString(test_part_result.line_number()) + 
": Failed\n" 
  476                 + FormatMessage(test_part_result.message())).Concat().Ln().Open(FormatPath(filename)).ToString())
 
  480 IUTEST_IPP_INLINE 
void SSTPNotifier::OnTestRecordProperty(
const TestProperty& test_property)
 
  483         .Script(Script(
"TestRecordProperty:" + StreamableToString(test_property.key())
 
  484             + 
"=" + test_property.value()).Concat().Ln().ToString())
 
  487 IUTEST_IPP_INLINE 
void SSTPNotifier::OnTestEnd(
const TestInfo& test_info)
 
  490         .Script(Script().Surface(test_info.Passed() ? Ghost::Smile : Ghost::Angry)
 
  491             .Append( FormatBool(test_info.Passed())
 
  492 #
if IUTEST_SSTPNOTIFIER_JAPANESE
 
  495             + 
"(" + StreamableToString(test_info.elapsed_time()) + 
"ms)").Concat().Ln().ToString())
 
  498 IUTEST_IPP_INLINE 
void SSTPNotifier::OnTestCaseEnd(
const TestCase& test_case)
 
  501         .Script(Script(StreamableToString(test_case.name())
 
  502 #
if IUTEST_SSTPNOTIFIER_JAPANESE
 
  503             + 
" テストケースは" + FormatBool(test_case.Passed()) + 
"したよ" 
  505             + 
" TestCase is"    + FormatBool(test_case.Passed()) + 
"." 
  507             + 
"(" + StreamableToString(test_case.elapsed_time()) + 
"ms)").Concat().Ln().ToString())
 
  510 IUTEST_IPP_INLINE 
void SSTPNotifier::OnTestIterationEnd(
const UnitTest& test
 
  513     IUTEST_UNUSED_VAR(test);
 
  514     IUTEST_UNUSED_VAR(iteration);
 
  516 IUTEST_IPP_INLINE 
void SSTPNotifier::OnTestProgramEnd(
const UnitTest& test)
 
  518     IUTEST_UNUSED_VAR(test);
 
  520 #if IUTEST_SSTPNOTIFIER_JAPANESE 
  521         .Script(Script(
"おわり").
Concat().Ln().ToString())
 
  523         .Script(Script(
"Finish!").
Concat().Ln().ToString())
 
  529 IUTEST_IPP_INLINE ::std::string SSTPNotifier::FormatMessage(const ::std::string& path)
 
  531     ::std::string str = path;
 
  532     detail::StringReplace(str, 
'\\', 
"/");
 
  536 IUTEST_IPP_INLINE ::std::string SSTPNotifier::FormatPath(const ::std::string& path)
 
  538     ::std::string str = path;
 
  539     detail::StringReplace(str, 
'\\', 
"/");
 
  543 IUTEST_IPP_INLINE ::std::string SSTPNotifier::FormatBool(
bool b)
 
  545 #if IUTEST_SSTPNOTIFIER_JAPANESE 
  546     return b ? 
"成功" : 
"失敗";
 
  548     return b ? 
"Succeeded" : 
"Failed";
 
  556 #endif // INCG_IRIS_IUTEST_SSTP_NOTIFIER_HPP_1187A63F_E99B_4289_A562_3C87B9739B7D_