mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			281 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			281 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright (c) 2016 The Chromium Embedded Framework 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 "include/cef_pack_strings.h"
 | 
						|
#include "include/views/cef_textfield.h"
 | 
						|
#include "include/views/cef_textfield_delegate.h"
 | 
						|
#include "include/wrapper/cef_closure_task.h"
 | 
						|
#include "tests/unittests/thread_helper.h"
 | 
						|
#include "tests/unittests/views/test_window_delegate.h"
 | 
						|
 | 
						|
#include "base/bind.h"
 | 
						|
#include "testing/gtest/include/gtest/gtest.h"
 | 
						|
#include "ui/events/keycodes/keyboard_codes.h"
 | 
						|
 | 
						|
#define TEXTFIELD_TEST(name) UI_THREAD_TEST(ViewsTextfieldTest, name)
 | 
						|
#define TEXTFIELD_TEST_ASYNC(name) \
 | 
						|
    UI_THREAD_TEST_ASYNC(ViewsTextfieldTest, name)
 | 
						|
 | 
						|
namespace {
 | 
						|
 | 
						|
void TextfieldContentsImpl() {
 | 
						|
  CefRefPtr<CefTextfield> textfield = CefTextfield::CreateTextfield(nullptr);
 | 
						|
  EXPECT_TRUE(textfield.get());
 | 
						|
  EXPECT_TRUE(textfield->AsTextfield().get());
 | 
						|
 | 
						|
  // Test defaults.
 | 
						|
  EXPECT_TRUE(textfield->GetText().empty());
 | 
						|
  EXPECT_FALSE(textfield->HasSelection());
 | 
						|
  EXPECT_EQ(CefRange(0, 0), textfield->GetSelectedRange());
 | 
						|
  EXPECT_EQ(0U, textfield->GetCursorPosition());
 | 
						|
 | 
						|
  // Test set/get text.
 | 
						|
  const char kText[] = "My test message!";
 | 
						|
  textfield->SetText(kText);
 | 
						|
  EXPECT_STREQ(kText, textfield->GetText().ToString().c_str());
 | 
						|
 | 
						|
  size_t cursor_pos = sizeof(kText) - 1;
 | 
						|
  EXPECT_EQ(cursor_pos, textfield->GetCursorPosition());
 | 
						|
 | 
						|
  // Test append text.
 | 
						|
  const char kAppendText[] = " And more.";
 | 
						|
  textfield->AppendText(kAppendText);
 | 
						|
  EXPECT_STREQ((std::string(kText) + kAppendText).c_str(),
 | 
						|
               textfield->GetText().ToString().c_str());
 | 
						|
  EXPECT_EQ(cursor_pos, textfield->GetCursorPosition());
 | 
						|
 | 
						|
  // Test select range.
 | 
						|
  EXPECT_FALSE(textfield->HasSelection());
 | 
						|
  EXPECT_EQ(CefRange(static_cast<int>(cursor_pos),
 | 
						|
                     static_cast<int>(cursor_pos)),
 | 
						|
            textfield->GetSelectedRange());
 | 
						|
  textfield->SelectRange(CefRange(0, static_cast<int>(cursor_pos)));
 | 
						|
  EXPECT_TRUE(textfield->HasSelection());
 | 
						|
  EXPECT_EQ(CefRange(0, static_cast<int>(cursor_pos)),
 | 
						|
            textfield->GetSelectedRange());
 | 
						|
  EXPECT_STREQ(kText, textfield->GetSelectedText().ToString().c_str());
 | 
						|
  EXPECT_EQ(cursor_pos, textfield->GetCursorPosition());
 | 
						|
 | 
						|
  // Test insert or replace.
 | 
						|
  const char kReplaceText[] = "Other text.";
 | 
						|
  textfield->InsertOrReplaceText(kReplaceText);
 | 
						|
  EXPECT_STREQ((std::string(kReplaceText) + kAppendText).c_str(),
 | 
						|
               textfield->GetText().ToString().c_str());
 | 
						|
 | 
						|
  cursor_pos = sizeof(kReplaceText) - 1;
 | 
						|
  EXPECT_EQ(cursor_pos, textfield->GetCursorPosition());
 | 
						|
 | 
						|
  // Test select all.
 | 
						|
  EXPECT_FALSE(textfield->HasSelection());
 | 
						|
  textfield->SelectAll(false);
 | 
						|
  EXPECT_TRUE(textfield->HasSelection());
 | 
						|
 | 
						|
  cursor_pos = sizeof(kReplaceText) + sizeof(kAppendText) - 2;
 | 
						|
  EXPECT_EQ(CefRange(0, static_cast<int>(cursor_pos)),
 | 
						|
            textfield->GetSelectedRange());
 | 
						|
  EXPECT_EQ(cursor_pos, textfield->GetCursorPosition());
 | 
						|
 | 
						|
  // Test clear selection.
 | 
						|
  textfield->ClearSelection();
 | 
						|
  EXPECT_FALSE(textfield->HasSelection());
 | 
						|
  EXPECT_EQ(CefRange(static_cast<int>(cursor_pos),
 | 
						|
                     static_cast<int>(cursor_pos)),
 | 
						|
            textfield->GetSelectedRange());
 | 
						|
  EXPECT_EQ(cursor_pos, textfield->GetCursorPosition());
 | 
						|
 | 
						|
  // Test selection with command.
 | 
						|
  EXPECT_TRUE(textfield->IsCommandEnabled(IDS_APP_SELECT_ALL));
 | 
						|
  textfield->ExecuteCommand(IDS_APP_SELECT_ALL);
 | 
						|
  EXPECT_TRUE(textfield->HasSelection());
 | 
						|
  EXPECT_EQ(CefRange(0, static_cast<int>(cursor_pos)),
 | 
						|
            textfield->GetSelectedRange());
 | 
						|
  EXPECT_EQ(cursor_pos, textfield->GetCursorPosition());
 | 
						|
 | 
						|
  textfield->ClearEditHistory();
 | 
						|
}
 | 
						|
 | 
						|
void TextfieldStyleImpl() {
 | 
						|
  CefRefPtr<CefTextfield> textfield = CefTextfield::CreateTextfield(nullptr);
 | 
						|
  EXPECT_TRUE(textfield.get());
 | 
						|
 | 
						|
  // Test defaults.
 | 
						|
  EXPECT_FALSE(textfield->IsPasswordInput());
 | 
						|
  EXPECT_FALSE(textfield->IsReadOnly());
 | 
						|
 | 
						|
  // Test password input.
 | 
						|
  textfield->SetPasswordInput(true);
 | 
						|
  EXPECT_TRUE(textfield->IsPasswordInput());
 | 
						|
  textfield->SetPasswordInput(false);
 | 
						|
  EXPECT_FALSE(textfield->IsPasswordInput());
 | 
						|
 | 
						|
  // Test read only.
 | 
						|
  textfield->SetReadOnly(true);
 | 
						|
  EXPECT_TRUE(textfield->IsReadOnly());
 | 
						|
  textfield->SetReadOnly(false);
 | 
						|
  EXPECT_FALSE(textfield->IsReadOnly());
 | 
						|
 | 
						|
  // Test colors.
 | 
						|
  const cef_color_t color = CefColorSetARGB(255, 255, 0, 255);
 | 
						|
 | 
						|
  EXPECT_NE(color, textfield->GetTextColor());
 | 
						|
  textfield->SetTextColor(color);
 | 
						|
  EXPECT_EQ(color, textfield->GetTextColor());
 | 
						|
 | 
						|
  EXPECT_NE(color, textfield->GetSelectionTextColor());
 | 
						|
  textfield->SetSelectionTextColor(color);
 | 
						|
  EXPECT_EQ(color, textfield->GetSelectionTextColor());
 | 
						|
 | 
						|
  EXPECT_NE(color, textfield->GetSelectionBackgroundColor());
 | 
						|
  textfield->SetSelectionBackgroundColor(color);
 | 
						|
  EXPECT_EQ(color, textfield->GetSelectionBackgroundColor());
 | 
						|
 | 
						|
  EXPECT_NE(color, textfield->GetPlaceholderTextColor());
 | 
						|
  textfield->SetPlaceholderTextColor(color);
 | 
						|
  EXPECT_EQ(color, textfield->GetPlaceholderTextColor());
 | 
						|
 | 
						|
  // Test fonts.
 | 
						|
  textfield->SetFontList("Arial, 14px");
 | 
						|
 | 
						|
  // Test format ranges.
 | 
						|
  const char kText[] = "test text";
 | 
						|
  textfield->SetText(kText);
 | 
						|
  textfield->ApplyTextColor(color, CefRange(0, 5));
 | 
						|
  textfield->ApplyTextStyle(CEF_TEXT_STYLE_BOLD, true, CefRange(0, 5));
 | 
						|
 | 
						|
  // Test placeholder text.
 | 
						|
  textfield->SetPlaceholderText(kText);
 | 
						|
  EXPECT_STREQ(kText, textfield->GetPlaceholderText().ToString().c_str());
 | 
						|
 | 
						|
  textfield->SetAccessibleName("MyTextfield");
 | 
						|
}
 | 
						|
 | 
						|
}  // namespace
 | 
						|
 | 
						|
// Test Textfield getters/setters.
 | 
						|
TEXTFIELD_TEST(TextfieldContents);
 | 
						|
TEXTFIELD_TEST(TextfieldStyle);
 | 
						|
 | 
						|
 | 
						|
namespace {
 | 
						|
 | 
						|
const int kTextfieldID = 1;
 | 
						|
 | 
						|
// Contents need to be supported by the TranslateKey function.
 | 
						|
const char kTestInputMessage[] = "Test Message";
 | 
						|
 | 
						|
void TranslateKey(int c, int* keycode, uint32* modifiers) {
 | 
						|
  *keycode = ui::VKEY_UNKNOWN;
 | 
						|
  *modifiers = 0;
 | 
						|
 | 
						|
  if (c >= 'a' && c <= 'z') {
 | 
						|
    *keycode = ui::VKEY_A + (c - 'a');
 | 
						|
  } else if (c >= 'A' && c <= 'Z') {
 | 
						|
    *keycode = ui::VKEY_A + (c - 'A');
 | 
						|
    *modifiers = EVENTFLAG_SHIFT_DOWN;
 | 
						|
  } else if (c == ' ') {
 | 
						|
    *keycode = ui::VKEY_SPACE;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
class TestTextfieldDelegate : public CefTextfieldDelegate {
 | 
						|
 public:
 | 
						|
  TestTextfieldDelegate() {
 | 
						|
  }
 | 
						|
 | 
						|
  bool OnKeyEvent(CefRefPtr<CefTextfield> textfield,
 | 
						|
                  const CefKeyEvent& event) override {
 | 
						|
    EXPECT_TRUE(textfield.get());
 | 
						|
    EXPECT_EQ(textfield->GetID(), kTextfieldID);
 | 
						|
 | 
						|
    if (event.type == KEYEVENT_RAWKEYDOWN &&
 | 
						|
        event.windows_key_code == ui::VKEY_RETURN) {
 | 
						|
      // Got the whole string. Finish the test asynchronously.
 | 
						|
      CefPostTask(TID_UI,
 | 
						|
          base::Bind(&TestTextfieldDelegate::FinishTest, this, textfield));
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
 | 
						|
    if (event.type == KEYEVENT_CHAR) {
 | 
						|
      int keycode;
 | 
						|
      uint32 modifiers;
 | 
						|
      TranslateKey(kTestInputMessage[index_++], &keycode, &modifiers);
 | 
						|
 | 
						|
      EXPECT_EQ(keycode, event.windows_key_code);
 | 
						|
      EXPECT_EQ(modifiers, event.modifiers);
 | 
						|
    }
 | 
						|
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  void OnAfterUserAction(CefRefPtr<CefTextfield> textfield) override {
 | 
						|
    after_user_action_ct_++;
 | 
						|
  }
 | 
						|
 | 
						|
 private:
 | 
						|
  void FinishTest(CefRefPtr<CefTextfield> textfield) {
 | 
						|
    // OnAfterUserAction() should be called for each unhandled character.
 | 
						|
    EXPECT_EQ(sizeof(kTestInputMessage) - 1, after_user_action_ct_);
 | 
						|
 | 
						|
    // Verify the completed contents.
 | 
						|
    EXPECT_STREQ(kTestInputMessage, textfield->GetText().ToString().c_str());
 | 
						|
 | 
						|
    // Close the window to end the test.
 | 
						|
    textfield->GetWindow()->Close();
 | 
						|
  }
 | 
						|
 | 
						|
  int index_ = 0;
 | 
						|
  size_t after_user_action_ct_ = 0;
 | 
						|
 | 
						|
  IMPLEMENT_REFCOUNTING(TestTextfieldDelegate);
 | 
						|
  DISALLOW_COPY_AND_ASSIGN(TestTextfieldDelegate);
 | 
						|
};
 | 
						|
 | 
						|
void RunTextfieldKeyEvent(CefRefPtr<CefWindow> window) {
 | 
						|
  CefRefPtr<CefTextfield> textfield = CefTextfield::CreateTextfield(
 | 
						|
      new TestTextfieldDelegate());
 | 
						|
  textfield->SetID(kTextfieldID);
 | 
						|
 | 
						|
  EXPECT_TRUE(textfield->AsTextfield());
 | 
						|
  EXPECT_EQ(kTextfieldID, textfield->GetID());
 | 
						|
  EXPECT_TRUE(textfield->IsVisible());
 | 
						|
  EXPECT_FALSE(textfield->IsDrawn());
 | 
						|
 | 
						|
  window->AddChildView(textfield);
 | 
						|
  window->Layout();
 | 
						|
 | 
						|
  EXPECT_TRUE(window->IsSame(textfield->GetWindow()));
 | 
						|
  EXPECT_TRUE(window->IsSame(textfield->GetParentView()));
 | 
						|
  EXPECT_TRUE(textfield->IsSame(window->GetViewForID(kTextfieldID)));
 | 
						|
  EXPECT_TRUE(textfield->IsVisible());
 | 
						|
  EXPECT_TRUE(textfield->IsDrawn());
 | 
						|
 | 
						|
  window->Show();
 | 
						|
 | 
						|
  // Give input focus to the textfield.
 | 
						|
  textfield->RequestFocus();
 | 
						|
 | 
						|
  // Send the contents of |kTestInputMessage| to the textfield.
 | 
						|
  for (size_t i = 0; i < sizeof(kTestInputMessage) - 1; ++i) {
 | 
						|
    int keycode;
 | 
						|
    uint32 modifiers;
 | 
						|
    TranslateKey(kTestInputMessage[i], &keycode, &modifiers);
 | 
						|
    window->SendKeyPress(keycode, modifiers);
 | 
						|
  }
 | 
						|
 | 
						|
  // Send return to end the text input.
 | 
						|
  window->SendKeyPress(ui::VKEY_RETURN, 0);
 | 
						|
}
 | 
						|
 | 
						|
void TextfieldKeyEventImpl(base::WaitableEvent* event) {
 | 
						|
  TestWindowDelegate::RunTest(event,
 | 
						|
      base::Bind(RunTextfieldKeyEvent), false, false);
 | 
						|
}
 | 
						|
 | 
						|
}  // namespace
 | 
						|
 | 
						|
// Test Textfield input and events. This is primarily to exercise exposed CEF
 | 
						|
// APIs and is not intended to comprehensively test Textfield-related behavior
 | 
						|
// (which we presume that Chromium is testing).
 | 
						|
TEXTFIELD_TEST_ASYNC(TextfieldKeyEvent);
 |