diff options
-rw-r--r-- | chrome/chrome.gyp | 4 | ||||
-rw-r--r-- | chrome/renderer/mock_printer.cc | 214 | ||||
-rw-r--r-- | chrome/renderer/mock_printer.h | 155 | ||||
-rw-r--r-- | chrome/renderer/mock_printer_driver_win.cc | 125 | ||||
-rw-r--r-- | chrome/renderer/mock_printer_driver_win.h | 25 | ||||
-rw-r--r-- | chrome/renderer/mock_render_thread.cc | 40 | ||||
-rw-r--r-- | chrome/renderer/mock_render_thread.h | 13 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 1 | ||||
-rw-r--r-- | chrome/renderer/render_view_unittest.cc | 88 | ||||
-rw-r--r-- | chrome/test/unit/unittests.vcproj | 16 |
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> |