1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "config.h"
6#include "core/html/HTMLSelectElement.h"
7
8#include "core/frame/FrameView.h"
9#include "core/html/HTMLDocument.h"
10#include "core/html/forms/FormController.h"
11#include "core/loader/EmptyClients.h"
12#include "core/testing/DummyPageHolder.h"
13#include <gtest/gtest.h>
14
15namespace blink {
16
17class HTMLSelectElementTest : public::testing::Test {
18protected:
19    virtual void SetUp() OVERRIDE;
20    HTMLDocument& document() const { return *m_document; }
21
22private:
23    OwnPtr<DummyPageHolder> m_dummyPageHolder;
24    RefPtrWillBePersistent<HTMLDocument> m_document;
25};
26
27void HTMLSelectElementTest::SetUp()
28{
29    Page::PageClients pageClients;
30    fillWithEmptyClients(pageClients);
31    m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600), &pageClients);
32
33    m_document = toHTMLDocument(&m_dummyPageHolder->document());
34    m_document->setMimeType("text/html");
35    m_document->setCharset("utf-8");
36}
37
38TEST_F(HTMLSelectElementTest, SaveRestoreSelectSingleFormControlState)
39{
40    document().documentElement()->setInnerHTML(String("<!DOCTYPE HTML><select id='sel'>"
41        "<option value='111' id='0'>111</option>"
42        "<option value='222'>222</option>"
43        "<option value='111' selected id='2'>!666</option>"
44        "<option value='999'>999</option></select>"), ASSERT_NO_EXCEPTION);
45    document().view()->updateLayoutAndStyleIfNeededRecursive();
46    Element* element = document().getElementById("sel");
47    HTMLFormControlElementWithState* select = toHTMLSelectElement(element);
48    HTMLOptionElement* opt0 = toHTMLOptionElement(document().getElementById("0"));
49    HTMLOptionElement* opt2 = toHTMLOptionElement(document().getElementById("2"));
50
51    // Save the select element state, and then restore again.
52    // Test passes if the restored state is not changed.
53    EXPECT_EQ(2, toHTMLSelectElement(element)->selectedIndex());
54    EXPECT_FALSE(opt0->selected());
55    EXPECT_TRUE(opt2->selected());
56    FormControlState selectState = select->saveFormControlState();
57    EXPECT_EQ(2U, selectState.valueSize());
58
59    // Clear the selected state, to be restored by restoreFormControlState.
60    toHTMLSelectElement(select)->setSelectedIndex(-1);
61    ASSERT_FALSE(opt2->selected());
62
63    // Restore
64    select->restoreFormControlState(selectState);
65    EXPECT_EQ(2, toHTMLSelectElement(element)->selectedIndex());
66    EXPECT_FALSE(opt0->selected());
67    EXPECT_TRUE(opt2->selected());
68}
69
70TEST_F(HTMLSelectElementTest, SaveRestoreSelectMultipleFormControlState)
71{
72    document().documentElement()->setInnerHTML(String("<!DOCTYPE HTML><select id='sel' multiple>"
73        "<option value='111' id='0'>111</option>"
74        "<option value='222'>222</option>"
75        "<option value='111' selected id='2'>!666</option>"
76        "<option value='999' selected id='3'>999</option></select>"), ASSERT_NO_EXCEPTION);
77    document().view()->updateLayoutAndStyleIfNeededRecursive();
78    HTMLFormControlElementWithState* select = toHTMLSelectElement(document().getElementById("sel"));
79
80    HTMLOptionElement* opt0 = toHTMLOptionElement(document().getElementById("0"));
81    HTMLOptionElement* opt2 = toHTMLOptionElement(document().getElementById("2"));
82    HTMLOptionElement* opt3 = toHTMLOptionElement(document().getElementById("3"));
83
84    // Save the select element state, and then restore again.
85    // Test passes if the selected options are not changed.
86    EXPECT_FALSE(opt0->selected());
87    EXPECT_TRUE(opt2->selected());
88    EXPECT_TRUE(opt3->selected());
89    FormControlState selectState = select->saveFormControlState();
90    EXPECT_EQ(4U, selectState.valueSize());
91
92    // Clear the selected state, to be restored by restoreFormControlState.
93    opt2->setSelected(false);
94    opt3->setSelected(false);
95    ASSERT_FALSE(opt2->selected());
96    ASSERT_FALSE(opt3->selected());
97
98    // Restore
99    select->restoreFormControlState(selectState);
100    EXPECT_FALSE(opt0->selected());
101    EXPECT_TRUE(opt2->selected());
102    EXPECT_TRUE(opt3->selected());
103}
104
105} // namespace blink
106