chromium/ipc/ipc_test_sink.h

// Copyright 2011 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef IPC_IPC_TEST_SINK_H_
#define IPC_IPC_TEST_SINK_H_

#include <stddef.h>
#include <stdint.h>

#include <utility>
#include <vector>

#include "base/observer_list.h"
#include "build/build_config.h"
#include "ipc/ipc_channel.h"

namespace IPC {

class Message;

// This test sink provides a "sink" for IPC messages that are sent. It allows
// the caller to query messages received in various different ways.  It is
// designed for tests for objects that use the IPC system.
//
// Typical usage:
//
//   test_sink.ClearMessages();
//   do_something();
//
//   // We should have gotten exactly one update state message.
//   EXPECT_TRUE(test_sink.GetUniqeMessageMatching(ViewHostMsg_Update::ID));
//   // ...and no start load messages.
//   EXPECT_FALSE(test_sink.GetFirstMessageMatching(ViewHostMsg_Start::ID));
//
//   // Now inspect a message. This assumes a message that was declared like
//   // this: IPC_MESSAGE_ROUTED2(ViewMsg_Foo, bool, int)
//   IPC::Message* msg = test_sink.GetFirstMessageMatching(ViewMsg_Foo::ID));
//   ASSERT_TRUE(msg);
//   bool first_param;
//   int second_param;
//   ViewMsg_Foo::Read(msg, &first_param, &second_param);
//
//   // Go on to the next phase of the test.
//   test_sink.ClearMessages();
//
// To read a sync reply, do this:
//
//   IPC::Message* msg = test_sink.GetUniqueMessageMatching(IPC_REPLY_ID);
//   ASSERT_TRUE(msg);
//   base::TupleTypes<ViewHostMsg_Foo::ReplyParam>::ValueTuple reply_data;
//   EXPECT_TRUE(ViewHostMsg_Foo::ReadReplyParam(msg, &reply_data));
//
// You can also register to be notified when messages are posted to the sink.
// This can be useful if you need to wait for a particular message that will
// be posted asynchronously.  Example usage:
//
//   class MyListener : public IPC::Listener {
//    public:
//     MyListener(const base::RepeatingClosure& closure)
//       : message_received_closure_(closure) {}
//     virtual bool OnMessageReceived(const IPC::Message& msg) {
//       <do something with the message>
//       message_received_closure_.Run();
//       return false;  // to store the message in the sink, or true to drop it
//     }
//    private:
//     base::RepeatingClosure message_received_closure_;
//   };
//
//   base::RunLoop run_loop;
//   MyListener listener(run_loop.QuitClosure());
//   test_sink.AddFilter(&listener);
//   StartSomeAsynchronousProcess(&test_sink);
//   run_loop.Run();
//   <inspect the results>
//   ...
//
// To hook up the sink, all you need to do is call OnMessageReceived when a
// message is received.
class TestSink : public Channel {};

}  // namespace IPC

#endif  // IPC_IPC_TEST_SINK_H_