| Index: content/renderer/media/media_recorder_handler_unittest.cc | 
| diff --git a/content/renderer/media/media_recorder_handler_unittest.cc b/content/renderer/media/media_recorder_handler_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..ce07b03ec458ab53be2994583ced911caac6f428 | 
| --- /dev/null | 
| +++ b/content/renderer/media/media_recorder_handler_unittest.cc | 
| @@ -0,0 +1,131 @@ | 
| +// Copyright 2015 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "base/run_loop.h" | 
| +#include "base/strings/utf_string_conversions.h" | 
| +#include "content/child/child_process.h" | 
| +#include "content/renderer/media/media_recorder_handler.h" | 
| +#include "content/renderer/media/mock_media_stream_registry.h" | 
| +#include "media/base/video_frame.h" | 
| +#include "testing/gmock/include/gmock/gmock.h" | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| +#include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h" | 
| +#include "third_party/WebKit/public/platform/WebString.h" | 
| + | 
| +using ::testing::_; | 
| +using ::testing::AtLeast; | 
| +using ::testing::InSequence; | 
| +using ::testing::Mock; | 
| +using ::testing::SaveArg; | 
| + | 
| +namespace content { | 
| + | 
| +ACTION_P(RunClosure, closure) { | 
| +  closure.Run(); | 
| +} | 
| + | 
| +static const std::string kTestStreamUrl = "stream_url"; | 
| +static const std::string kTestVideoTrackId = "video_track_id"; | 
| + | 
| +// MediaRecorderHandler needs a meaningful WebMediaStream with at least a | 
| +// WebMediaStreamTrack - MediaStreamVideoTrack couple. We also need a | 
| +// WebMediaStreamSource - MockMediaStreamVideoSource (connected via | 
| +// ExtraData()), so VideoFrames can be injected in the pipeline using | 
| +// DeliverVideoFrame(). | 
| +class MediaRecorderHandlerTest | 
| +    : public testing::Test | 
| +    , public blink::WebMediaRecorderHandlerClient { | 
| + public: | 
| +  MediaRecorderHandlerTest() { | 
| +    EXPECT_FALSE(media_recorder_handler_.recording_); | 
| + | 
| +    registry_.Init(kTestStreamUrl); | 
| +    registry_.AddVideoTrack(kTestVideoTrackId); | 
| +  } | 
| + | 
| +  MOCK_METHOD3(writeData, void(const char*, size_t, bool)); | 
| + | 
| +  bool recording() const { return media_recorder_handler_.recording_; } | 
| +  bool hasVideoRecorders() const { | 
| +    return !media_recorder_handler_.video_recorders_.empty(); | 
| +  } | 
| + | 
| +  void OnVideoFrameForTesting(const scoped_refptr<media::VideoFrame>& frame) { | 
| +    media_recorder_handler_.OnVideoFrameForTesting(frame, | 
| +                                                   base::TimeTicks::Now()); | 
| +  } | 
| + | 
| +  MediaRecorderHandler media_recorder_handler_; | 
| + | 
| +  // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks | 
| +  // and Sources in |registry_| into believing they are on the right threads. | 
| +  const base::MessageLoopForUI message_loop_; | 
| +  ChildProcess child_process_; | 
| + | 
| +  MockMediaStreamRegistry registry_; | 
| + | 
| + private: | 
| +  DISALLOW_COPY_AND_ASSIGN(MediaRecorderHandlerTest); | 
| +}; | 
| + | 
| +TEST_F(MediaRecorderHandlerTest, CanSupportMimeType) { | 
| +  const blink::WebString mime_type(base::UTF8ToUTF16("video/vp8")); | 
| +  EXPECT_FALSE(media_recorder_handler_.canSupportMimeType(mime_type)); | 
| +} | 
| + | 
| +TEST_F(MediaRecorderHandlerTest, InitializeStartStop) { | 
| +  const blink::WebString mime_type(base::UTF8ToUTF16("video/vp8")); | 
| +  EXPECT_TRUE(media_recorder_handler_.initialize(this, | 
| +                                                 registry_.test_stream(), | 
| +                                                 mime_type)); | 
| +  EXPECT_FALSE(recording()); | 
| +  EXPECT_FALSE(hasVideoRecorders()); | 
| + | 
| +  EXPECT_TRUE(media_recorder_handler_.start()); | 
| +  EXPECT_TRUE(recording()); | 
| +  EXPECT_TRUE(hasVideoRecorders()); | 
| + | 
| +  media_recorder_handler_.stop(); | 
| +  EXPECT_FALSE(recording()); | 
| +  EXPECT_FALSE(hasVideoRecorders()); | 
| + | 
| +  // Expect a last call on destruction. | 
| +  EXPECT_CALL(*this, writeData(_, _, true)).Times(1); | 
| +} | 
| + | 
| +TEST_F(MediaRecorderHandlerTest, EncodeVideoFrames) { | 
| +  const blink::WebString mime_type(base::UTF8ToUTF16("video/vp8")); | 
| +  EXPECT_TRUE(media_recorder_handler_.initialize(this, | 
| +                                                 registry_.test_stream(), | 
| +                                                 mime_type)); | 
| +  EXPECT_FALSE(recording()); | 
| +  EXPECT_FALSE(hasVideoRecorders()); | 
| + | 
| +  EXPECT_TRUE(media_recorder_handler_.start()); | 
| + | 
| +  InSequence s; | 
| +  size_t packetised_length = 0; | 
| +  // writeData() is pinged a number of times as the WebM header is written; the | 
| +  // last time it is called it has the encoded data. | 
| +  EXPECT_CALL(*this, writeData(_, _, false)) | 
| +      .Times(AtLeast(1)) | 
| +      .WillRepeatedly(SaveArg<1>(&packetised_length)); | 
| +  // Expect a last call on destruction. | 
| +  EXPECT_CALL(*this, writeData(_, 0, true)).Times(1); | 
| + | 
| +  const gfx::Size frame_size(160, 80); | 
| +  const scoped_refptr<media::VideoFrame> video_frame = | 
| +      media::VideoFrame::CreateBlackFrame(frame_size); | 
| +  OnVideoFrameForTesting(video_frame); | 
| + | 
| +  child_process_.io_message_loop()->RunUntilIdle(); | 
| +  base::RunLoop().RunUntilIdle(); | 
| + | 
| +  const size_t kFirstEncodedDataSize = 52; | 
| +  EXPECT_EQ(packetised_length, kFirstEncodedDataSize); | 
| + | 
| +  media_recorder_handler_.stop(); | 
| +} | 
| + | 
| +}  // namespace content | 
|  |