diff options
author | nona@chromium.org <nona@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-21 06:56:15 +0000 |
---|---|---|
committer | nona@chromium.org <nona@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-21 06:56:15 +0000 |
commit | fac9bc9d2486f9e2b379e911989b239fd360a661 (patch) | |
tree | adb04884b327f72a643afee51e2566ca27c5331b /chromeos | |
parent | 53b30342892134b637db027afd53a7a6d4e6f7f0 (diff) | |
download | chromium_src-fac9bc9d2486f9e2b379e911989b239fd360a661.zip chromium_src-fac9bc9d2486f9e2b379e911989b239fd360a661.tar.gz chromium_src-fac9bc9d2486f9e2b379e911989b239fd360a661.tar.bz2 |
Implement IBusProperty
IBusProperty and IBusPropertyList are one of representations an obeject used in communication with ibus-daemon.
According to this CL, ibus_property.cc will be comipled and tested but not in
used production binary at thi moment.
BUG=chromium-os:26334
TEST=chromeos_unittests, unit_tests, dbus_unittests
Review URL: https://chromiumcodereview.appspot.com/10383253
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@143355 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos')
-rw-r--r-- | chromeos/chromeos.gyp | 3 | ||||
-rw-r--r-- | chromeos/dbus/ibus/ibus_object.cc | 26 | ||||
-rw-r--r-- | chromeos/dbus/ibus/ibus_object.h | 13 | ||||
-rw-r--r-- | chromeos/dbus/ibus/ibus_object_unittest.cc | 43 | ||||
-rw-r--r-- | chromeos/dbus/ibus/ibus_property.cc | 184 | ||||
-rw-r--r-- | chromeos/dbus/ibus/ibus_property.h | 137 | ||||
-rw-r--r-- | chromeos/dbus/ibus/ibus_property_unittest.cc | 122 |
7 files changed, 527 insertions, 1 deletions
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp index ed89b2f..dff9498 100644 --- a/chromeos/chromeos.gyp +++ b/chromeos/chromeos.gyp @@ -79,6 +79,8 @@ 'dbus/ibus/ibus_lookup_table.h', 'dbus/ibus/ibus_object.cc', 'dbus/ibus/ibus_object.h', + 'dbus/ibus/ibus_property.cc', + 'dbus/ibus/ibus_property.h', 'dbus/ibus/ibus_text.cc', 'dbus/ibus/ibus_text.h', 'dbus/ibus/ibus_input_context_client.cc', @@ -224,6 +226,7 @@ 'dbus/ibus/ibus_client_unittest.cc', 'dbus/ibus/ibus_lookup_table_unittest.cc', 'dbus/ibus/ibus_object_unittest.cc', + 'dbus/ibus/ibus_property_unittest.cc', 'dbus/ibus/ibus_text_unittest.cc', 'dbus/ibus/ibus_input_context_client_unittest.cc', 'dbus/introspectable_client_unittest.cc', diff --git a/chromeos/dbus/ibus/ibus_object.cc b/chromeos/dbus/ibus/ibus_object.cc index faa0249..641ed55 100644 --- a/chromeos/dbus/ibus/ibus_object.cc +++ b/chromeos/dbus/ibus/ibus_object.cc @@ -5,6 +5,7 @@ #include "chromeos/dbus/ibus/ibus_object.h" #include "base/logging.h" +#include "chromeos/dbus/ibus/ibus_property.h" #include "chromeos/dbus/ibus/ibus_text.h" #include "dbus/message.h" @@ -146,6 +147,20 @@ bool IBusObjectReader::PopStringFromIBusText(std::string* text) { contents_reader_.get(), text); } +bool IBusObjectReader::PopIBusProperty(IBusProperty* property) { + DCHECK_NE(IBUS_OBJECT_NOT_CHECKED, check_result_); + DCHECK(contents_reader_.get()); + return IsValid() && chromeos::ibus::PopIBusProperty(contents_reader_.get(), + property); +} + +bool IBusObjectReader::PopIBusPropertyList(IBusPropertyList* properties) { + DCHECK_NE(IBUS_OBJECT_NOT_CHECKED, check_result_); + DCHECK(contents_reader_.get()); + return IsValid() && chromeos::ibus::PopIBusPropertyList( + contents_reader_.get(), properties); +} + bool IBusObjectReader::HasMoreData() { DCHECK_NE(IBUS_OBJECT_NOT_CHECKED, check_result_); DCHECK(contents_reader_.get()); @@ -215,6 +230,17 @@ void IBusObjectWriter::AppendStringAsIBusText(const std::string& text) { chromeos::ibus::AppendStringAsIBusText(text, contents_writer_.get()); } +void IBusObjectWriter::AppendIBusProperty(const IBusProperty& property) { + DCHECK(IsInitialized()); + chromeos::ibus::AppendIBusProperty(property, contents_writer_.get()); +} + +void IBusObjectWriter::AppendIBusPropertyList( + const IBusPropertyList& property_list) { + DCHECK(IsInitialized()); + chromeos::ibus::AppendIBusPropertyList(property_list, contents_writer_.get()); +} + void IBusObjectWriter::CloseContainer(dbus::MessageWriter* writer) { DCHECK(IsInitialized()); contents_writer_->CloseContainer(writer); diff --git a/chromeos/dbus/ibus/ibus_object.h b/chromeos/dbus/ibus/ibus_object.h index 275fc71..b6cf45c 100644 --- a/chromeos/dbus/ibus/ibus_object.h +++ b/chromeos/dbus/ibus/ibus_object.h @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "chromeos/chromeos_export.h" +#include "chromeos/dbus/ibus/ibus_property.h" #include "chromeos/dbus/ibus/ibus_text.h" namespace dbus { @@ -122,6 +123,12 @@ class CHROMEOS_EXPORT IBusObjectReader { // Return true on success. bool PopStringFromIBusText(std::string* text); + // Pops a IBusProperty. + bool PopIBusProperty(ibus::IBusProperty* property); + + // Pops a IBusPropertyList. + bool PopIBusPropertyList(ibus::IBusPropertyList* property_list); + private: enum CheckResult { IBUS_OBJECT_VALID, // Already checked and valid type. @@ -197,6 +204,12 @@ class CHROMEOS_EXPORT IBusObjectWriter { // instead in the case of using any attribute entries. void AppendStringAsIBusText(const std::string& text); + // Appends a IBusProperty. + void AppendIBusProperty(const ibus::IBusProperty& property); + + // Appends a IBusPropertyList. + void AppendIBusPropertyList(const ibus::IBusPropertyList& property_list); + private: // Appends IBusObject headers, should be called once. void Init(); diff --git a/chromeos/dbus/ibus/ibus_object_unittest.cc b/chromeos/dbus/ibus/ibus_object_unittest.cc index dd543ea..468e268 100644 --- a/chromeos/dbus/ibus/ibus_object_unittest.cc +++ b/chromeos/dbus/ibus/ibus_object_unittest.cc @@ -6,6 +6,7 @@ #include "chromeos/dbus/ibus/ibus_object.h" #include <string> +#include <vector> #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "dbus/message.h" @@ -146,7 +147,7 @@ TEST(IBusObjectTest, PopAppendStringAsIBusText) { ibus_object_writer.AppendStringAsIBusText(kSampleString); ibus_object_writer.CloseAll(); - // Read string from IBusText; + // Read string from IBusText. dbus::MessageReader reader(message.get()); IBusObjectReader ibus_object_reader(kSampleTypeName, &reader); std::string result_str; @@ -210,5 +211,45 @@ TEST(IBusObjectTest, AttachmentTest) { EXPECT_EQ(kSampleText, value); } +TEST(IBusObjectTest, PopAppendIBusPropertyTest) { + const char kSampleTypeName[] = "Empty IBusObject Name"; + const char kSampleKey[] = "Key"; + const IBusProperty::IBusPropertyType kSampleType = + IBusProperty::IBUS_PROPERTY_TYPE_MENU; + const char kSampleLabel[] = "Label"; + const char kSampleTooltip[] = "Tooltip"; + const bool kSampleVisible = true; + const bool kSampleChecked = false; + scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); + + // Create IBusProperty. + ibus::IBusProperty property; + property.set_key(kSampleKey); + property.set_type(kSampleType); + property.set_label(kSampleLabel); + property.set_tooltip(kSampleTooltip); + property.set_visible(kSampleVisible); + property.set_checked(kSampleChecked); + + // Write a IBusProperty. + dbus::MessageWriter writer(response.get()); + IBusObjectWriter ibus_object_writer(kSampleTypeName, "v", &writer); + ibus_object_writer.AppendIBusProperty(property); + ibus_object_writer.CloseAll(); + + // Read string from IBusText. + dbus::MessageReader reader(response.get()); + IBusObjectReader ibus_object_reader(kSampleTypeName, &reader); + ibus::IBusProperty result_property; + ASSERT_TRUE(ibus_object_reader.Init()); + ASSERT_TRUE(ibus_object_reader.PopIBusProperty(&result_property)); + EXPECT_EQ(kSampleKey, result_property.key()); + EXPECT_EQ(kSampleType, result_property.type()); + EXPECT_EQ(kSampleLabel, result_property.label()); + EXPECT_EQ(kSampleTooltip, result_property.tooltip()); + EXPECT_EQ(kSampleVisible, result_property.visible()); + EXPECT_EQ(kSampleChecked, result_property.checked()); +} + } // namespace ibus } // namespace chromeos diff --git a/chromeos/dbus/ibus/ibus_property.cc b/chromeos/dbus/ibus/ibus_property.cc new file mode 100644 index 0000000..86c6890 --- /dev/null +++ b/chromeos/dbus/ibus/ibus_property.cc @@ -0,0 +1,184 @@ +// Copyright (c) 2012 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 "chromeos/dbus/ibus/ibus_property.h" + +#include <string> +#include "base/logging.h" +#include "chromeos/dbus/ibus/ibus_object.h" +#include "chromeos/dbus/ibus/ibus_text.h" +#include "dbus/message.h" + +namespace chromeos { +// TODO(nona): remove ibus namespace after complete libibus removal. +namespace ibus { + +namespace { +// Following variables indicate state of IBusProperty. +const uint32 kIBusPropertyStateUnchecked = 0; +const uint32 kIBusPropertyStateChecked = 1; +const uint32 kIBusPropertyStateInconsistent = 2; +}; + +bool CHROMEOS_EXPORT PopIBusProperty(dbus::MessageReader* reader, + IBusProperty* property) { + IBusObjectReader ibus_property_reader("IBusProperty", reader); + if (!ibus_property_reader.Init()) + return false; + + std::string key; + if (!ibus_property_reader.PopString(&key)) { + LOG(ERROR) << "Invalid variant structure[IBusProperty]: " + << "1st argument should be string."; + return false; + } + property->set_key(key); + + uint32 type = 0; + if (!ibus_property_reader.PopUint32(&type)) { + LOG(ERROR) << "Invalid variant structure[IBusProperty]: " + << "2nd argument should be unsigned 32bit integer."; + return false; + } + if (type > 4UL) { + LOG(ERROR) << "Invalid value for IBusProperty type"; + return false; + } + property->set_type(static_cast<IBusProperty::IBusPropertyType>(type)); + + std::string label; + if (!ibus_property_reader.PopStringFromIBusText(&label)) { + LOG(ERROR) << "Invalid variant structure[IBusProperty]: " + << "3rd argument should be IBusText."; + return false; + } + property->set_label(label); + + // The 4th string argument represents icon path, but not supported in + // Chrome OS. + std::string icon; + if (!ibus_property_reader.PopString(&icon)) { + LOG(ERROR) << "Invalid variant structure[IBusProperty]: " + << "4th argument should be string."; + } + + std::string tooltip; + if (!ibus_property_reader.PopStringFromIBusText(&tooltip)) { + LOG(ERROR) << "Invalid variant structure[IBusProperty]: " + << "5th argument should be IBusText."; + return false; + } + property->set_tooltip(tooltip); + + // The 6th bool argument represents whther the property is event sensitive or + // not, but not supported in Chrome OS. + bool sensitive = true; + if (!ibus_property_reader.PopBool(&sensitive)) { + LOG(ERROR) << "Invalid variant structure[IBusProperty]: " + << "6th argument should be boolean."; + } + + bool visible = true; + if (!ibus_property_reader.PopBool(&visible)) { + LOG(ERROR) << "Invalid variant structure[IBusProperty]: " + << "7th argument should be boolean."; + return false; + } + property->set_visible(visible); + + uint32 state = 0; + if (!ibus_property_reader.PopUint32(&state)) { + LOG(ERROR) << "Invalid variant structure[IBusProperty]: " + << "8th argument should be unsigned 32bit integer."; + return false; + } + + if (type > 3UL) { + LOG(ERROR) << "Invalid value for IBusProperty."; + return false; + } + + DCHECK_LE(state, 3UL); + if (state == kIBusPropertyStateInconsistent) { + LOG(ERROR) << "PROP_STATE_INCONSISTENT is not supported in Chrome OS."; + } else { + property->set_checked(state == kIBusPropertyStateChecked); + } + + if (!ibus_property_reader.PopIBusPropertyList( + property->mutable_sub_properties())) { + LOG(ERROR) << "Invalid variant structure[IBusProperty]: " + << "9th argument should be IBusPropList."; + return false; + } + + return true; +} + +bool CHROMEOS_EXPORT PopIBusPropertyList(dbus::MessageReader* reader, + IBusPropertyList* property_list) { + IBusObjectReader ibus_property_reader("IBusPropList", reader); + if (!ibus_property_reader.Init()) + return false; + + dbus::MessageReader property_array_reader(NULL); + if (!ibus_property_reader.PopArray(&property_array_reader)) { + LOG(ERROR) << "Invalid variant structure[IBusPropList]: " + << "1st argument should be array."; + return false; + } + property_list->reset(); + while (property_array_reader.HasMoreData()) { + IBusProperty* property = new IBusProperty; + if (!PopIBusProperty(&property_array_reader, property)) { + LOG(ERROR) << "Invalid variant structure[IBusPropList]: " + << "1st argument should be array of IBusProperty."; + return false; + } + property_list->push_back(property); + } + + return true; +} + +void CHROMEOS_EXPORT AppendIBusProperty(const IBusProperty& property, + dbus::MessageWriter* writer) { + IBusObjectWriter ibus_property_writer("IBusProperty", "suvsvbbuv", writer); + ibus_property_writer.AppendString(property.key()); + ibus_property_writer.AppendUint32(static_cast<uint32>(property.type())); + ibus_property_writer.AppendStringAsIBusText(property.label()); + ibus_property_writer.AppendString(""); // The icon path is not supported. + ibus_property_writer.AppendStringAsIBusText(property.tooltip()); + // The event sensitive field is not supported. + ibus_property_writer.AppendBool(false); + ibus_property_writer.AppendBool(property.visible()); + ibus_property_writer.AppendUint32(static_cast<uint32>(property.checked())); + ibus_property_writer.AppendIBusPropertyList(property.sub_properties()); + ibus_property_writer.CloseAll(); +} + +void CHROMEOS_EXPORT AppendIBusPropertyList( + const IBusPropertyList& property_list, + dbus::MessageWriter* writer) { + IBusObjectWriter ibus_property_list_writer("IBusPropList", "av", writer); + dbus::MessageWriter property_list_writer(NULL); + ibus_property_list_writer.OpenArray("v", &property_list_writer); + for (size_t i = 0; i < property_list.size(); ++i) { + AppendIBusProperty(*(property_list[i]), &property_list_writer); + } + ibus_property_list_writer.CloseContainer(&property_list_writer); + ibus_property_list_writer.CloseAll(); +} + + +/////////////////////////////////////////////////////////////////////////////// +// IBusProperty +IBusProperty::IBusProperty() { +} + +IBusProperty::~IBusProperty() { +} + +} // namespace ibus +} // namespace chromeos diff --git a/chromeos/dbus/ibus/ibus_property.h b/chromeos/dbus/ibus/ibus_property.h new file mode 100644 index 0000000..4b5d5ff --- /dev/null +++ b/chromeos/dbus/ibus/ibus_property.h @@ -0,0 +1,137 @@ +// Copyright (c) 2012 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 CHROMEOS_DBUS_IBUS_IBUS_PROPERTY_H_ +#define CHROMEOS_DBUS_IBUS_IBUS_PROPERTY_H_ + +#include <string> +#include "base/basictypes.h" +#include "base/memory/scoped_vector.h" +#include "chromeos/chromeos_export.h" + +namespace dbus { +class MessageWriter; +class MessageReader; +} // namespace dbus + +namespace chromeos { +namespace ibus { + +class IBusProperty; +typedef ScopedVector<IBusProperty> IBusPropertyList; + +// Pops a IBusProperty from |reader|. +// Returns false if an error occures. +bool CHROMEOS_EXPORT PopIBusProperty(dbus::MessageReader* reader, + IBusProperty* property); +// Pops a IBusPropertyList from |reader|. +// Returns false if an error occures. +bool CHROMEOS_EXPORT PopIBusPropertyList(dbus::MessageReader* reader, + IBusPropertyList* property_list); + +// Appends a IBusProperty to |writer|. +void CHROMEOS_EXPORT AppendIBusProperty(const IBusProperty& property, + dbus::MessageWriter* writer); +// Appends a IBusPropertyList to |writer|. +void CHROMEOS_EXPORT AppendIBusPropertyList( + const IBusPropertyList& property_list, + dbus::MessageWriter* writer); + +// The IBusPropList is one of IBusObjects and it contains array of IBusProperty. +// The IBusProperty contains IBusTexts but only plain string is used in Chrome. +// We treat IBusPropList as scoped_vector of IBusProperty. +// +// DATA STRUCTURE OVERVIEW: +// variant struct { +// string "IBusProperty" +// array [] +// string "CompositionMode" // Key +// uint32 3 // Type +// variant struct { // Label +// string "IBusText" +// array [] +// string "" +// variant struct { +// string "IBusAttrList" +// array [] +// array [] +// } +// } +// string "/usr/share/ibus-mozc/hiragana.png" // icon +// variant struct { // Tooltip +// string "IBusText" +// array [] +// string "" +// variant struct { +// string "IBusAttrList" +// array [] +// array [] +// } +// } +// boolean true // sensitive +// boolean true // visible +// uint32 0 // state +// variant struct { // sub properties +// string "IBusPropList" +// array [] +// array [ +// ... More IBusPropertys +// ] +// } +// } +class CHROMEOS_EXPORT IBusProperty { + public: + enum IBusPropertyType { + IBUS_PROPERTY_TYPE_NORMAL = 0, + IBUS_PROPERTY_TYPE_TOGGLE, + IBUS_PROPERTY_TYPE_RADIO, + IBUS_PROPERTY_TYPE_MENU, + IBUS_PROPERTY_TYPE_SEPARATOR, + }; + IBusProperty(); + virtual ~IBusProperty(); + + // The identity for the IBusProperty. + std::string key() const { return key_; } + void set_key(const std::string& key) { key_ = key; } + + // The type of property: + IBusPropertyType type() const { return type_; } + void set_type(IBusPropertyType type) { type_ = type; } + + // The string to be shown in UI. + std::string label() const { return label_; } + void set_label(const std::string& label) { label_ = label; } + + // The string to be shown in UI as tooltip. + std::string tooltip() const { return tooltip_; } + void set_tooltip(const std::string& tooltip) { tooltip_ = tooltip; } + + // True if the property is visible. + bool visible() const { return visible_; } + void set_visible(bool visible) { visible_ = visible; } + + // True if the property is checked. + bool checked() const { return checked_; } + void set_checked(bool checked) { checked_ = checked; } + + const IBusPropertyList& sub_properties() const { return sub_properties_; } + IBusPropertyList* mutable_sub_properties() { return &sub_properties_; } + + private: + std::string key_; + IBusPropertyType type_; + std::string label_; + std::string tooltip_; + bool visible_; + bool checked_; + IBusPropertyList sub_properties_; + + DISALLOW_COPY_AND_ASSIGN(IBusProperty); +}; + +} // namespace ibus +} // namespace chromeos + +#endif // CHROMEOS_DBUS_IBUS_IBUS_PROPERTY_H_ diff --git a/chromeos/dbus/ibus/ibus_property_unittest.cc b/chromeos/dbus/ibus/ibus_property_unittest.cc new file mode 100644 index 0000000..9eca37f --- /dev/null +++ b/chromeos/dbus/ibus/ibus_property_unittest.cc @@ -0,0 +1,122 @@ +// Copyright (c) 2012 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 "chromeos/dbus/ibus/ibus_property.h" + +#include <string> + +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/stringprintf.h" +#include "chromeos/dbus/ibus/ibus_object.h" +#include "dbus/message.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { +namespace ibus { + +namespace { + +const char kSampleKey[] = "Key"; +const IBusProperty::IBusPropertyType kSampleType = + IBusProperty::IBUS_PROPERTY_TYPE_RADIO; +const char kSampleLabel[] = "Label"; +const char kSampleTooltip[] = "Tooltip"; +const bool kSampleVisible = true; +const bool kSampleChecked = false; + +// Sets testing data to |property| with |prefix|. +// This function clears IBusProperty::sub_properties_ and does not add any +// entries into it. The testing data can be checked with CheckProperty function +// with same |prefix|. +void SetProperty(const std::string& prefix, IBusProperty* property) { + property->set_key(prefix + kSampleKey); + property->set_type(kSampleType); + property->set_label(prefix + kSampleLabel); + property->set_tooltip(prefix + kSampleTooltip); + property->set_visible(kSampleVisible); + property->set_checked(kSampleChecked); + property->mutable_sub_properties()->reset(); +} + +// Checks testing data in |property| with |prefix|. +// This function does not check IBusProperty::sub_properties_. +bool CheckProperty(const std::string& prefix, const IBusProperty& property) { + if ((prefix + kSampleKey) != property.key()) { + LOG(ERROR) << "Does not match IBusProperty::key value: " << std::endl + << "Expected: " << (prefix + kSampleKey) << std::endl + << "Actual: " << property.key(); + return false; + } + if (kSampleType != property.type()) { + LOG(ERROR) << "Does not match IBusProperty::type value: " << std::endl + << "Expected: " << kSampleType << std::endl + << "Actual: " << property.type(); + return false; + } + if ((prefix + kSampleLabel) != property.label()) { + LOG(ERROR) << "Does not match IBusProperty::label value: " << std::endl + << "Expected: " << (prefix + kSampleLabel) << std::endl + << "Actual: " << property.label(); + return false; + } + if ((prefix + kSampleTooltip) != property.tooltip()) { + LOG(ERROR) << "Does not match IBusProperty::tooltip value: " << std::endl + << "Expected: " << (prefix + kSampleTooltip) << std::endl + << "Actual: " << property.tooltip(); + return false; + } + if (kSampleVisible != property.visible()) { + LOG(ERROR) << "Does not match IBusProperty::visible value: " << std::endl + << "Expected: " << kSampleVisible << std::endl + << "Actual: " << property.visible(); + return false; + } + if (kSampleChecked != property.checked()) { + LOG(ERROR) << "Does not match IBusProperty::state value: " << std::endl + << "Expected: " << kSampleChecked << std::endl + << "Actual: " << property.checked(); + return false; + } + return true; +} + +} // namespace + +TEST(IBusPropertyListTest, WriteReadIBusPropertyTest) { + const size_t kSubPropertyCount = 16; + + // Create a IBusProperty. + IBusProperty property; + SetProperty("Root_", &property); + for (size_t i = 0; i < kSubPropertyCount; ++i) { + const std::string prefix = base::StringPrintf("Sub%lu_", i); + IBusProperty* sub_property = new IBusProperty; + SetProperty(prefix, sub_property); + property.mutable_sub_properties()->push_back(sub_property); + } + + // Write a IBusProperty. + scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); + dbus::MessageWriter writer(response.get()); + AppendIBusProperty(property, &writer); + + // Read a IBusProperty. + IBusProperty target_property; + dbus::MessageReader reader(response.get()); + PopIBusProperty(&reader, &target_property); + + // Check a result. + EXPECT_TRUE(CheckProperty("Root_", target_property)); + const IBusPropertyList& sub_properties = target_property.sub_properties(); + ASSERT_EQ(kSubPropertyCount, sub_properties.size()); + for (size_t i = 0; i < kSubPropertyCount; ++i) { + const std::string prefix = base::StringPrintf("Sub%lu_", i); + EXPECT_TRUE(CheckProperty(prefix, *(sub_properties[i]))); + } +} + +} // namespace ibus +} // namespace chromeos |