summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/chrome.gyp4
-rw-r--r--chrome/renderer/mock_printer.cc214
-rw-r--r--chrome/renderer/mock_printer.h155
-rw-r--r--chrome/renderer/mock_printer_driver_win.cc125
-rw-r--r--chrome/renderer/mock_printer_driver_win.h25
-rw-r--r--chrome/renderer/mock_render_thread.cc40
-rw-r--r--chrome/renderer/mock_render_thread.h13
-rw-r--r--chrome/renderer/render_view.h1
-rw-r--r--chrome/renderer/render_view_unittest.cc88
-rw-r--r--chrome/test/unit/unittests.vcproj16
10 files changed, 670 insertions, 11 deletions
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index bc1b351..52408d4 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -2504,6 +2504,10 @@
'renderer/mock_render_process.h',
'renderer/mock_render_thread.cc',
'renderer/mock_render_thread.h',
+ 'renderer/mock_printer.cc',
+ 'renderer/mock_printer.h',
+ 'renderer/mock_printer_driver_win.cc',
+ 'renderer/mock_printer_driver_win.h',
'test/automation/autocomplete_edit_proxy.cc',
'test/automation/autocomplete_edit_proxy.h',
'test/automation/automation_constants.h',
diff --git a/chrome/renderer/mock_printer.cc b/chrome/renderer/mock_printer.cc
new file mode 100644
index 0000000..88f9909
--- /dev/null
+++ b/chrome/renderer/mock_printer.cc
@@ -0,0 +1,214 @@
+// Copyright (c) 2009 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 "chrome/renderer/mock_printer.h"
+
+#include "base/file_util.h"
+#include "base/gfx/png_encoder.h"
+#include "base/logging.h"
+#include "base/md5.h"
+#include "base/shared_memory.h"
+#include "chrome/common/ipc_message_utils.h"
+#include "chrome/common/render_messages.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+MockPrinter::MockPrinter()
+ : printable_width_(0),
+ printable_height_(0),
+ dpi_(72),
+ max_shrink_(2.0),
+ min_shrink_(1.25),
+ desired_dpi_(72),
+ document_cookie_(-1),
+ current_document_cookie_(0),
+ printer_status_(PRINTER_READY),
+ number_pages_(0),
+ page_number_(0) {
+ printable_width_ = static_cast<int>(dpi_ * 8.5);
+ printable_height_ = static_cast<int>(dpi_ * 11.0);
+}
+
+MockPrinter::~MockPrinter() {
+}
+
+void MockPrinter::ResetPrinter() {
+ printer_status_ = PRINTER_READY;
+ document_cookie_ = -1;
+}
+
+void MockPrinter::GetDefaultPrintSettings(ViewMsg_Print_Params* params) {
+ // Verify this printer is not processing a job.
+ // Sorry, this mock printer is very fragile.
+ EXPECT_EQ(-1, document_cookie_);
+
+ // Assign a unit document cookie and set the print settings.
+ document_cookie_ = CreateDocumentCookie();
+ memset(params, 0, sizeof(ViewMsg_Print_Params));
+ params->dpi = dpi_;
+ params->max_shrink = max_shrink_;
+ params->min_shrink = min_shrink_;
+ params->desired_dpi = desired_dpi_;
+ params->document_cookie = document_cookie_;
+ params->printable_size.set_width(printable_width_);
+ params->printable_size.set_height(printable_height_);
+}
+
+void MockPrinter::SetDefaultPrintSettings(const ViewMsg_Print_Params& params) {
+ dpi_ = params.dpi;
+ max_shrink_ = params.max_shrink;
+ min_shrink_ = params.min_shrink;
+ desired_dpi_ = params.desired_dpi;
+ printable_width_ = params.printable_size.width();
+ printable_height_ = params.printable_size.height();
+}
+
+void MockPrinter::ScriptedPrint(int cookie,
+ int expected_pages_count,
+ ViewMsg_PrintPages_Params* settings) {
+ // Verify the input parameters.
+ EXPECT_EQ(document_cookie_, cookie);
+
+ memset(settings, 0, sizeof(ViewMsg_PrintPages_Params));
+ settings->params.dpi = dpi_;
+ settings->params.max_shrink = max_shrink_;
+ settings->params.min_shrink = min_shrink_;
+ settings->params.desired_dpi = desired_dpi_;
+ settings->params.document_cookie = document_cookie_;
+ settings->params.printable_size.set_width(printable_width_);
+ settings->params.printable_size.set_height(printable_height_);
+ printer_status_ = PRINTER_PRINTING;
+}
+
+void MockPrinter::SetPrintedPagesCount(int cookie, int number_pages) {
+ // Verify the input parameter and update the printer status so that the
+ // RenderViewTest class can verify the this function finishes without errors.
+ EXPECT_EQ(document_cookie_, cookie);
+ EXPECT_EQ(PRINTER_PRINTING, printer_status_);
+ EXPECT_EQ(0, number_pages_);
+ EXPECT_EQ(0, page_number_);
+
+ // Initialize the job status.
+ number_pages_ = number_pages;
+ page_number_ = 0;
+ pages_.clear();
+}
+
+void MockPrinter::PrintPage(const ViewHostMsg_DidPrintPage_Params& params) {
+ // Verify the input parameter and update the printer status so that the
+ // RenderViewTest class can verify the this function finishes without errors.
+ EXPECT_EQ(PRINTER_PRINTING, printer_status_);
+ EXPECT_EQ(document_cookie_, params.document_cookie);
+ EXPECT_EQ(page_number_, params.page_number);
+ EXPECT_LE(params.page_number, number_pages_);
+
+#if defined(OS_WIN)
+ // Load the EMF data sent from a RenderView object and create a PageData
+ // object.
+ // We duplicate the given file handle when creating a base::SharedMemory
+ // instance so that its destructor closes the copy.
+ EXPECT_GT(params.data_size, 0U);
+ base::SharedMemory emf_data(params.emf_data_handle, true,
+ GetCurrentProcess());
+ emf_data.Map(params.data_size);
+ MockPrinterPage* page_data = driver_.LoadSource(emf_data.memory(),
+ params.data_size);
+ if (!page_data) {
+ printer_status_ = PRINTER_ERROR;
+ return;
+ }
+
+ scoped_refptr<MockPrinterPage> page(page_data);
+ pages_.push_back(page);
+#endif
+
+ // We finish printing a printing job.
+ // Reset the job status and the printer status.
+ ++page_number_;
+ if (number_pages_ == page_number_)
+ ResetPrinter();
+}
+
+int MockPrinter::GetPrintedPages() const {
+ if (printer_status_ != PRINTER_READY)
+ return -1;
+ return page_number_;
+}
+
+int MockPrinter::GetWidth(size_t page) const {
+ if (printer_status_ != PRINTER_READY || page >= pages_.size())
+ return -1;
+ return pages_[page]->width();
+}
+
+int MockPrinter::GetHeight(size_t page) const {
+ if (printer_status_ != PRINTER_READY || page >= pages_.size())
+ return -1;
+ return pages_[page]->height();
+}
+
+bool MockPrinter::GetSourceChecksum(size_t page, std::string* checksum) const {
+ if (printer_status_ != PRINTER_READY || page >= pages_.size())
+ return false;
+ return GetChecksum(pages_[page]->source_data(), pages_[page]->source_size(),
+ checksum);
+}
+
+bool MockPrinter::GetBitmapChecksum(size_t page, std::string* checksum) const {
+ if (printer_status_ != PRINTER_READY || page >= pages_.size())
+ return false;
+ return GetChecksum(pages_[page]->bitmap_data(), pages_[page]->bitmap_size(),
+ checksum);
+}
+
+bool MockPrinter::GetBitmap(size_t page,
+ const void** data,
+ size_t* size) const {
+ if (printer_status_ != PRINTER_READY || page >= pages_.size())
+ return false;
+ *data = pages_[page]->bitmap_data();
+ *size = pages_[page]->bitmap_size();
+ return true;
+}
+
+bool MockPrinter::SaveSource(size_t page,
+ const std::wstring& filename) const {
+ if (printer_status_ != PRINTER_READY || page >= pages_.size())
+ return false;
+ const uint8* source_data = pages_[page]->source_data();
+ size_t source_size = pages_[page]->source_size();
+ file_util::WriteFile(filename, reinterpret_cast<const char*>(source_data),
+ source_size);
+ return true;
+}
+
+bool MockPrinter::SaveBitmap(size_t page,
+ const std::wstring& filename) const {
+ if (printer_status_ != PRINTER_READY || page >= pages_.size())
+ return false;
+ int width = pages_[page]->width();
+ int height = pages_[page]->height();
+ int row_byte_width = width * 4;
+ const uint8* bitmap_data = pages_[page]->bitmap_data();
+ std::vector<unsigned char> compressed;
+ PNGEncoder::Encode(bitmap_data,
+ PNGEncoder::FORMAT_BGRA, width, height,
+ row_byte_width, true, &compressed);
+ file_util::WriteFile(filename,
+ reinterpret_cast<char*>(&*compressed.begin()),
+ compressed.size());
+ return true;
+}
+
+int MockPrinter::CreateDocumentCookie() {
+ return ++current_document_cookie_;
+}
+
+bool MockPrinter::GetChecksum(const void* data,
+ size_t size,
+ std::string* checksum) const {
+ MD5Digest digest;
+ MD5Sum(data, size, &digest);
+ checksum->assign(HexEncode(&digest, sizeof(digest)));
+ return true;
+}
diff --git a/chrome/renderer/mock_printer.h b/chrome/renderer/mock_printer.h
new file mode 100644
index 0000000..bf318c1
--- /dev/null
+++ b/chrome/renderer/mock_printer.h
@@ -0,0 +1,155 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_RENDERER_MOCK_PRINTER_H_
+#define CHROME_RENDERER_MOCK_PRINTER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+
+#if defined(OS_WIN)
+#include "chrome/renderer/mock_printer_driver_win.h"
+#endif
+
+struct ViewMsg_Print_Params;
+struct ViewMsg_PrintPages_Params;
+struct ViewHostMsg_DidPrintPage_Params;
+
+// A class which represents an output page used in the MockPrinter class.
+// The MockPrinter class stores output pages in a vector, so, this class
+// inherits the base::RefCounted<> class so that the MockPrinter class can use
+// a smart pointer of this object (i.e. scoped_refptr<>).
+class MockPrinterPage : public base::RefCounted<MockPrinterPage> {
+ public:
+ MockPrinterPage()
+ : width_(0),
+ height_(0),
+ source_size_(0),
+ bitmap_size_(0) {
+ }
+
+ MockPrinterPage(int width,
+ int height,
+ const void* source_data,
+ size_t source_size,
+ const void* bitmap_data,
+ size_t bitmap_size)
+ : width_(width),
+ height_(height),
+ source_size_(source_size),
+ bitmap_size_(bitmap_size) {
+ // Create copies of the source data and the bitmap data.
+ source_data_.reset(new uint8[source_size]);
+ if (source_data_.get())
+ memcpy(source_data_.get(), source_data, source_size);
+ bitmap_data_.reset(new uint8[bitmap_size]);
+ if (bitmap_data_.get())
+ memcpy(bitmap_data_.get(), bitmap_data, bitmap_size);
+ }
+
+ ~MockPrinterPage() {
+ }
+
+ int width() { return width_; }
+ int height() { return height_; }
+ const uint8* source_data() { return source_data_.get(); }
+ const size_t source_size() { return source_size_; }
+ const uint8* bitmap_data() { return bitmap_data_.get(); }
+ const size_t bitmap_size() { return bitmap_size_; }
+
+ private:
+ int width_;
+ int height_;
+ size_t source_size_;
+ scoped_array<uint8> source_data_;
+ size_t bitmap_size_;
+ scoped_array<uint8> bitmap_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockPrinterPage);
+};
+
+// A class which implements a pseudo-printer object used by the RenderViewTest
+// class.
+// This class consists of three parts:
+// 1. An IPC-message hanlder sent from the RenderView class;
+// 2. A renderer that creates a printing job into bitmaps, and;
+// 3. A vector which saves the output pages of a printing job.
+// A user who writes RenderViewTest cases only use the functions which
+// retrieve output pages from this vector to verify them with expected results.
+class MockPrinter {
+ public:
+ enum Status {
+ PRINTER_READY,
+ PRINTER_PRINTING,
+ PRINTER_ERROR,
+ };
+
+ MockPrinter();
+ ~MockPrinter();
+
+ // Functions that changes settings of a pseudo printer.
+ void ResetPrinter();
+ void SetDefaultPrintSettings(const ViewMsg_Print_Params& params);
+
+ // Functions that handles IPC events.
+ void GetDefaultPrintSettings(ViewMsg_Print_Params* params);
+ void ScriptedPrint(int cookie,
+ int expected_pages_count,
+ ViewMsg_PrintPages_Params* settings);
+ void SetPrintedPagesCount(int cookie, int number_pages);
+ void PrintPage(const ViewHostMsg_DidPrintPage_Params& params);
+
+ // Functions that retrieve the output pages.
+ Status GetPrinterStatus() const { return printer_status_; }
+ int GetPrintedPages() const;
+ int GetWidth(size_t page) const;
+ int GetHeight(size_t page) const;
+ bool GetSourceChecksum(size_t page, std::string* checksum) const;
+ bool GetBitmapChecksum(size_t page, std::string* checksum) const;
+ bool GetSource(size_t page, const void** data, size_t* size) const;
+ bool GetBitmap(size_t page, const void** data, size_t* size) const;
+ bool SaveSource(size_t page, const std::wstring& filename) const;
+ bool SaveBitmap(size_t page, const std::wstring& filename) const;
+
+ protected:
+ int CreateDocumentCookie();
+ bool GetChecksum(const void* data, size_t size, std::string* checksum) const;
+
+ private:
+ // In pixels according to dpi_x and dpi_y.
+ int printable_width_;
+ int printable_height_;
+
+ // Specifies dots per inch.
+ double dpi_;
+ double max_shrink_;
+ double min_shrink_;
+
+ // Desired apparent dpi on paper.
+ int desired_dpi_;
+
+ // Cookie for the document to ensure correctness.
+ int document_cookie_;
+ int current_document_cookie_;
+
+ // The current status of this printer.
+ Status printer_status_;
+
+ // The output of a printing job.
+ int number_pages_;
+ int page_number_;
+ std::vector<scoped_refptr<MockPrinterPage> > pages_;
+
+#if defined(OS_WIN)
+ MockPrinterDriverWin driver_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(MockPrinter);
+};
+
+#endif // CHROME_RENDERER_MOCK_PRINTER_H_
diff --git a/chrome/renderer/mock_printer_driver_win.cc b/chrome/renderer/mock_printer_driver_win.cc
new file mode 100644
index 0000000..4232019
--- /dev/null
+++ b/chrome/renderer/mock_printer_driver_win.cc
@@ -0,0 +1,125 @@
+// Copyright (c) 2009 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 "chrome/renderer/mock_printer_driver_win.h"
+
+#include "base/gfx/gdi_util.h"
+#include "base/logging.h"
+#include "chrome/common/gfx/emf.h"
+#include "chrome/renderer/mock_printer.h"
+#include "skia/ext/platform_device.h"
+
+namespace {
+
+// A simple class which temporarily overrides system settings.
+// The bitmap image rendered via the PlayEnhMetaFile() function depends on
+// some system settings.
+// As a workaround for such dependency, this class saves the system settings
+// and changes them. This class also restore the saved settings in its
+// destructor.
+class SystemSettingsOverride {
+ public:
+ SystemSettingsOverride() : font_smoothing_(0) {
+ }
+
+ ~SystemSettingsOverride() {
+ SystemParametersInfo(SPI_SETFONTSMOOTHING, font_smoothing_, NULL, 0);
+ }
+
+ BOOL Init(BOOL font_smoothing) {
+ if (!SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &font_smoothing_, 0))
+ return FALSE;
+ return SystemParametersInfo(SPI_SETFONTSMOOTHING, font_smoothing, NULL, 0);
+ }
+
+ private:
+ BOOL font_smoothing_;
+};
+
+// A class which renders an EMF data and returns a raw bitmap data.
+// The bitmap data returned from Create() is deleted in the destructor of this
+// class. So, we need to create a copy of this bitmap data if it is used after
+// this object is deleted,
+class EmfRenderer {
+ public:
+ EmfRenderer() : dc_(NULL), bitmap_(NULL) {
+ }
+
+ ~EmfRenderer() {
+ if (bitmap_) {
+ DeleteObject(bitmap_);
+ bitmap_ = NULL;
+ }
+ if (dc_) {
+ DeleteDC(dc_);
+ dc_ = NULL;
+ }
+ }
+
+ const void* Create(int width, int height, const gfx::Emf* emf) {
+ CHECK(!dc_ && !bitmap_);
+
+ BITMAPV4HEADER header;
+ gfx::CreateBitmapV4Header(width, height, &header);
+
+ dc_ = CreateCompatibleDC(NULL);
+ if (!dc_)
+ return NULL;
+
+ void* bits;
+ bitmap_ = CreateDIBSection(dc_, reinterpret_cast<BITMAPINFO*>(&header), 0,
+ &bits, NULL, 0);
+ if (!bitmap_ || !bits)
+ return NULL;
+
+ SelectObject(dc_, bitmap_);
+
+ skia::PlatformDeviceWin::InitializeDC(dc_);
+ emf->Playback(dc_, NULL);
+
+ return reinterpret_cast<uint8*>(bits);
+ }
+
+ private:
+ HDC dc_;
+ HBITMAP bitmap_;
+};
+
+} // namespace
+
+MockPrinterDriverWin::MockPrinterDriverWin() {
+}
+
+MockPrinterDriverWin::~MockPrinterDriverWin() {
+}
+
+MockPrinterPage* MockPrinterDriverWin::LoadSource(const void* source_data,
+ size_t source_size) {
+ // This code is mostly copied from the Image::LoadEMF() function in
+ // "src/chrome/browser/printing/printing_layout_uitest.cc".
+ gfx::Emf emf;
+ emf.CreateFromData(source_data, source_size);
+ gfx::Rect rect(emf.GetBounds());
+
+ // Create a temporary DC and bitmap to retrieve the renderered data.
+ if (rect.width() <= 0 || rect.height() <= 0)
+ return NULL;
+
+ // Disable the font-smoothing feature of Windows.
+ SystemSettingsOverride system_settings;
+ system_settings.Init(FALSE);
+
+ // Render the EMF data and create a bitmap.
+ EmfRenderer renderer;
+ const void* bitmap_data = renderer.Create(rect.width(), rect.height(), &emf);
+ if (!bitmap_data)
+ return NULL;
+
+ // Create a new MockPrinterPage instance and return it.
+ size_t row_byte_width = rect.width() * 4;
+ size_t bitmap_size = row_byte_width * rect.height();
+ return new MockPrinterPage(rect.width(), rect.height(),
+ source_data, source_size,
+ bitmap_data, bitmap_size);
+}
diff --git a/chrome/renderer/mock_printer_driver_win.h b/chrome/renderer/mock_printer_driver_win.h
new file mode 100644
index 0000000..117aa16
--- /dev/null
+++ b/chrome/renderer/mock_printer_driver_win.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_RENDERER_MOCK_PRINTER_DRIVER_WIN_H_
+#define CHROME_RENDERER_MOCK_PRINTER_DRIVER_WIN_H_
+
+#include "base/basictypes.h"
+
+class MockPrinterPage;
+
+// Implements the platform-dependent part of a pseudo printer object.
+// This class renders a platform-dependent input and creates a MockPrinterPage
+// instance.
+class MockPrinterDriverWin {
+ public:
+ MockPrinterDriverWin();
+ ~MockPrinterDriverWin();
+
+ MockPrinterPage* LoadSource(const void* data, size_t size);
+
+ DISALLOW_COPY_AND_ASSIGN(MockPrinterDriverWin);
+};
+
+#endif // CHROME_RENDERER_MOCK_PRINTER_DRIVER_WIN_H_
diff --git a/chrome/renderer/mock_render_thread.cc b/chrome/renderer/mock_render_thread.cc
index 7812b31..8ff04a9 100644
--- a/chrome/renderer/mock_render_thread.cc
+++ b/chrome/renderer/mock_render_thread.cc
@@ -12,7 +12,8 @@ MockRenderThread::MockRenderThread()
: routing_id_(0),
opener_id_(0),
widget_(NULL),
- reply_deserializer_(NULL) {
+ reply_deserializer_(NULL),
+ printer_(new MockPrinter) {
}
MockRenderThread::~MockRenderThread() {
@@ -78,6 +79,10 @@ void MockRenderThread::OnMessageReceived(const IPC::Message& msg) {
OnGetDefaultPrintSettings);
IPC_MESSAGE_HANDLER(ViewHostMsg_ScriptedPrint,
OnScriptedPrint);
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DidGetPrintedPagesCount,
+ OnDidGetPrintedPagesCount)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DidPrintPage, OnDidPrintPage)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DuplicateSection, OnDuplicateSection)
#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
@@ -96,21 +101,34 @@ void MockRenderThread::OnMsgOpenChannelToExtension(
*channel_id = 0;
}
+void MockRenderThread::OnDuplicateSection(
+ base::SharedMemoryHandle renderer_handle,
+ base::SharedMemoryHandle* browser_handle) {
+ // We don't have to duplicate the input handles since RenderViewTest does not
+ // separate a browser process from a renderer process.
+ *browser_handle = renderer_handle;
+}
+
void MockRenderThread::OnGetDefaultPrintSettings(ViewMsg_Print_Params* params) {
- memset(params, 0, sizeof(ViewMsg_Print_Params));
- params->dpi = 72;
- params->desired_dpi = 72;
- params->document_cookie = 1;
- params->printable_size = gfx::Size(500, 500);
+ if (printer_.get())
+ printer_->GetDefaultPrintSettings(params);
}
void MockRenderThread::OnScriptedPrint(gfx::NativeViewId host_window,
int cookie,
int expected_pages_count,
ViewMsg_PrintPages_Params* settings) {
- memset(settings, 0, sizeof(ViewMsg_PrintPages_Params));
- settings->params.dpi = 72;
- settings->params.document_cookie = 1;
- settings->params.desired_dpi = 72;
- settings->params.printable_size = gfx::Size(500, 500);
+ if (printer_.get())
+ printer_->ScriptedPrint(cookie, expected_pages_count, settings);
+}
+
+void MockRenderThread::OnDidGetPrintedPagesCount(int cookie, int number_pages) {
+ if (printer_.get())
+ printer_->SetPrintedPagesCount(cookie, number_pages);
+}
+
+void MockRenderThread::OnDidPrintPage(
+ const ViewHostMsg_DidPrintPage_Params& params) {
+ if (printer_.get())
+ printer_->PrintPage(params);
}
diff --git a/chrome/renderer/mock_render_thread.h b/chrome/renderer/mock_render_thread.h
index e4f2403..ebca0df 100644
--- a/chrome/renderer/mock_render_thread.h
+++ b/chrome/renderer/mock_render_thread.h
@@ -9,6 +9,7 @@
#include <vector>
#include "chrome/common/ipc_test_sink.h"
+#include "chrome/renderer/mock_printer.h"
#include "chrome/renderer/render_thread.h"
struct ViewMsg_Print_Params;
@@ -64,6 +65,9 @@ class MockRenderThread : public RenderThreadBase {
// state.
void SendCloseMessage();
+ // Returns the pseudo-printer instance.
+ const MockPrinter* printer() const { return printer_.get(); }
+
private:
// This function operates as a regular IPC listener.
void OnMessageReceived(const IPC::Message& msg);
@@ -78,6 +82,9 @@ class MockRenderThread : public RenderThreadBase {
const std::string& extension_id,
int* channel_id);
+ void OnDuplicateSection(base::SharedMemoryHandle renderer_handle,
+ base::SharedMemoryHandle* browser_handle);
+
// The RenderView expects default print settings.
void OnGetDefaultPrintSettings(ViewMsg_Print_Params* setting);
@@ -87,6 +94,9 @@ class MockRenderThread : public RenderThreadBase {
int expected_pages_count,
ViewMsg_PrintPages_Params* settings);
+ void OnDidGetPrintedPagesCount(int cookie, int number_pages);
+ void OnDidPrintPage(const ViewHostMsg_DidPrintPage_Params& params);
+
IPC::TestSink sink_;
// Routing id what will be assigned to the Widget.
@@ -101,6 +111,9 @@ class MockRenderThread : public RenderThreadBase {
// The last known good deserializer for sync messages.
scoped_ptr<IPC::MessageReplyDeserializer> reply_deserializer_;
+
+ // A mock printer device used for printing tests.
+ scoped_ptr<MockPrinter> printer_;
};
#endif // CHROME_RENDERER_MOCK_RENDER_THREAD_H_
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 4de8bb3..744ef73 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -398,6 +398,7 @@ class RenderView : public RenderWidget,
FRIEND_TEST(RenderViewTest, ImeComposition);
FRIEND_TEST(RenderViewTest, OnSetTextDirection);
FRIEND_TEST(RenderViewTest, OnPrintPages);
+ FRIEND_TEST(RenderViewTest, PrintLayoutTest);
FRIEND_TEST(RenderViewTest, OnHandleKeyboardEvent);
FRIEND_TEST(RenderViewTest, InsertCharacters);
diff --git a/chrome/renderer/render_view_unittest.cc b/chrome/renderer/render_view_unittest.cc
index 8537583..781c62a 100644
--- a/chrome/renderer/render_view_unittest.cc
+++ b/chrome/renderer/render_view_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/file_util.h"
#include "chrome/common/native_web_keyboard_event.h"
#include "chrome/common/render_messages.h"
#include "chrome/test/render_view_test.h"
@@ -311,6 +312,93 @@ TEST_F(RenderViewTest, OnPrintPages) {
#endif
}
+// Tests if we can print a page and verify its results.
+// This test prints HTML pages into a pseudo printer and check their outputs,
+// i.e. a simplified version of the PrintingLayoutTextTest UI test.
+namespace {
+// Test cases used in this test.
+const struct {
+ const char* page;
+ int printed_pages;
+ int width;
+ int height;
+ const char* checksum;
+ const wchar_t* file;
+} kTestPages[] = {
+ {"<html>"
+ "<head>"
+ "<meta"
+ " http-equiv=\"Content-Type\""
+ " content=\"text/html; charset=utf-8\"/>"
+ "<title>Test 1</title>"
+ "</head>"
+ "<body style=\"background-color: white;\">"
+ "<p style=\"font-family: arial;\">Hello World!</p>"
+ "</body>",
+ 1, 764, 42,
+ NULL,
+ NULL,
+ },
+};
+} // namespace
+
+TEST_F(RenderViewTest, PrintLayoutTest) {
+#if defined(OS_WIN)
+ bool baseline = false;
+
+ EXPECT_TRUE(render_thread_.printer() != NULL);
+ for (size_t i = 0; i < arraysize(kTestPages); ++i) {
+ // Load an HTML page and print it.
+ LoadHTML(kTestPages[i].page);
+ view_->OnPrintPages();
+
+ // MockRenderThread::Send() just calls MockRenderThread::OnMsgReceived().
+ // So, all IPC messages sent in the above RenderView::OnPrintPages() call
+ // has been handled by the MockPrinter object, i.e. this printing job
+ // has been already finished.
+ // So, we can start checking the output pages of this printing job.
+ // Retrieve the number of pages actually printed.
+ size_t pages = render_thread_.printer()->GetPrintedPages();
+ EXPECT_EQ(kTestPages[i].printed_pages, pages);
+
+ // Retrieve the width and height of the output page.
+ int width = render_thread_.printer()->GetWidth(0);
+ int height = render_thread_.printer()->GetHeight(0);
+ EXPECT_EQ(kTestPages[i].width, width);
+ EXPECT_EQ(kTestPages[i].height, height);
+
+ // Retrieve the checksum of the bitmap data from the pseudo printer and
+ // compare it with the expected result.
+ std::string bitmap_actual;
+ EXPECT_TRUE(render_thread_.printer()->GetBitmapChecksum(0, &bitmap_actual));
+ if (kTestPages[i].checksum)
+ EXPECT_EQ(kTestPages[i].checksum, bitmap_actual);
+
+ // Retrieve the bitmap data from the pseudo printer.
+ // TODO(hbono): implement a function which retrieves an expected result
+ // from a file and compares it with this bitmap data.
+ const void* bitmap_data;
+ size_t bitmap_size;
+ EXPECT_TRUE(render_thread_.printer()->GetBitmap(0, &bitmap_data,
+ &bitmap_size));
+
+ if (baseline) {
+ // Save the source data and the bitmap data into temporary files to
+ // create base-line results.
+ FilePath source_path;
+ file_util::CreateTemporaryFileName(&source_path);
+ render_thread_.printer()->SaveSource(0, source_path.value());
+
+ FilePath bitmap_path;
+ file_util::CreateTemporaryFileName(&bitmap_path);
+ render_thread_.printer()->SaveBitmap(0, bitmap_path.value());
+ }
+ }
+#else
+ NOTIMPLEMENTED();
+#endif
+}
+
// Test that we can receive correct DOM events when we send input events
// through the RenderWidget::OnHandleInputEvent() function.
TEST_F(RenderViewTest, OnHandleKeyboardEvent) {
diff --git a/chrome/test/unit/unittests.vcproj b/chrome/test/unit/unittests.vcproj
index 6d967e4..d99a072 100644
--- a/chrome/test/unit/unittests.vcproj
+++ b/chrome/test/unit/unittests.vcproj
@@ -973,6 +973,22 @@
>
</File>
<File
+ RelativePath="..\..\renderer\mock_printer.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\renderer\mock_printer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\renderer\mock_printer_driver_win.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\renderer\mock_printer_driver_win.h"
+ >
+ </File>
+ <File
RelativePath="..\..\renderer\mock_render_process.h"
>
</File>