| Index: chrome/browser/extensions/extension_message_handler_unittest.cc
 | 
| ===================================================================
 | 
| --- chrome/browser/extensions/extension_message_handler_unittest.cc	(revision 0)
 | 
| +++ chrome/browser/extensions/extension_message_handler_unittest.cc	(revision 0)
 | 
| @@ -0,0 +1,276 @@
 | 
| +// 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/browser/extensions/extension_message_handler.h"
 | 
| +
 | 
| +#include <string>
 | 
| +
 | 
| +#include "base/scoped_ptr.h"
 | 
| +#include "base/string_util.h"
 | 
| +#include "base/values.h"
 | 
| +#include "testing/gtest/include/gtest/gtest.h"
 | 
| +
 | 
| +namespace {
 | 
| +
 | 
| +// Helper method for dictionary building.
 | 
| +void SetDictionary(const std::wstring name,
 | 
| +                   DictionaryValue* target,
 | 
| +                   DictionaryValue* subtree) {
 | 
| +  target->Set(name, static_cast<Value*>(subtree));
 | 
| +}
 | 
| +
 | 
| +void CreateContentTree(const std::wstring& name,
 | 
| +                       const std::string content,
 | 
| +                       DictionaryValue* dict) {
 | 
| +  DictionaryValue* content_tree = new DictionaryValue;
 | 
| +  content_tree->SetString(ExtensionMessageHandler::kContentKey, content);
 | 
| +  SetDictionary(name, dict, content_tree);
 | 
| +}
 | 
| +
 | 
| +void CreatePlaceholdersTree(DictionaryValue* dict) {
 | 
| +  DictionaryValue* placeholders_tree = new DictionaryValue;
 | 
| +  CreateContentTree(L"a", "A", placeholders_tree);
 | 
| +  CreateContentTree(L"b", "B", placeholders_tree);
 | 
| +  CreateContentTree(L"c", "C", placeholders_tree);
 | 
| +  SetDictionary(ExtensionMessageHandler::kPlaceholdersKey,
 | 
| +                dict,
 | 
| +                placeholders_tree);
 | 
| +}
 | 
| +
 | 
| +void CreateMessageTree(const std::wstring& name,
 | 
| +                       const std::string& message,
 | 
| +                       bool create_placeholder_subtree,
 | 
| +                       DictionaryValue* dict) {
 | 
| +  DictionaryValue* message_tree = new DictionaryValue;
 | 
| +  if (create_placeholder_subtree)
 | 
| +    CreatePlaceholdersTree(message_tree);
 | 
| +  message_tree->SetString(ExtensionMessageHandler::kMessageKey, message);
 | 
| +  SetDictionary(name, dict, message_tree);
 | 
| +}
 | 
| +
 | 
| +void CreateGoodDictionary(DictionaryValue* dict) {
 | 
| +  dict->Clear();
 | 
| +  CreateMessageTree(L"n1", "message1 $a$ $b$", true, dict);
 | 
| +  CreateMessageTree(L"n2", "message2 $c$", true, dict);
 | 
| +  CreateMessageTree(L"n3", "message3", false, dict);
 | 
| +}
 | 
| +
 | 
| +enum BadDictionary {
 | 
| +  INVALID_NAME,
 | 
| +  NAME_NOT_A_TREE,
 | 
| +  EMPTY_NAME_TREE,
 | 
| +  MISSING_MESSAGE,
 | 
| +  PLACEHOLDER_NOT_A_TREE,
 | 
| +  EMPTY_PLACEHOLDER_TREE,
 | 
| +  CONTENT_MISSING,
 | 
| +  MESSAGE_PLACEHOLDER_DOESNT_MATCH,
 | 
| +};
 | 
| +
 | 
| +void CreateBadDictionary(DictionaryValue* dict,
 | 
| +                         enum BadDictionary what_is_bad) {
 | 
| +  CreateGoodDictionary(dict);
 | 
| +  // Now remove/break things.
 | 
| +  switch (what_is_bad) {
 | 
| +    case INVALID_NAME:
 | 
| +      CreateMessageTree(L"n 5", "nevermind", false, dict);
 | 
| +      break;
 | 
| +    case NAME_NOT_A_TREE:
 | 
| +      dict->SetString(L"n4", "whatever");
 | 
| +      break;
 | 
| +    case EMPTY_NAME_TREE: {
 | 
| +        DictionaryValue* empty_tree = new DictionaryValue;
 | 
| +        SetDictionary(L"n4", dict, empty_tree);
 | 
| +      }
 | 
| +      break;
 | 
| +    case MISSING_MESSAGE:
 | 
| +      dict->Remove(L"n1.message", NULL);
 | 
| +      break;
 | 
| +    case PLACEHOLDER_NOT_A_TREE:
 | 
| +      dict->SetString(L"n1.placeholders", "whatever");
 | 
| +      break;
 | 
| +    case EMPTY_PLACEHOLDER_TREE: {
 | 
| +        DictionaryValue* empty_tree = new DictionaryValue;
 | 
| +        SetDictionary(L"n1.placeholders", dict, empty_tree);
 | 
| +      }
 | 
| +      break;
 | 
| +    case CONTENT_MISSING:
 | 
| +       dict->Remove(L"n1.placeholders.a.content", NULL);
 | 
| +      break;
 | 
| +    case MESSAGE_PLACEHOLDER_DOESNT_MATCH:
 | 
| +      DictionaryValue* value;
 | 
| +      dict->Remove(L"n1.placeholders.a", NULL);
 | 
| +      dict->GetDictionary(L"n1.placeholders", &value);
 | 
| +      CreateContentTree(L"x", "X", value);
 | 
| +      break;
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +TEST(ExtensionMessageHandler, InitEmptyDictionaries) {
 | 
| +  DictionaryValue default_dict;
 | 
| +  DictionaryValue app_dict;
 | 
| +  std::string error;
 | 
| +  ExtensionMessageHandler handler;
 | 
| +
 | 
| +  EXPECT_TRUE(handler.Init(&default_dict, &app_dict, &error));
 | 
| +  EXPECT_EQ(0U, handler.GetDictionarySize());
 | 
| +}
 | 
| +
 | 
| +TEST(ExtensionMessageHandler, InitGoodDefaultDictEmptyAppDict) {
 | 
| +  DictionaryValue default_dict;
 | 
| +  DictionaryValue app_dict;
 | 
| +  std::string error;
 | 
| +  ExtensionMessageHandler handler;
 | 
| +
 | 
| +  CreateGoodDictionary(&default_dict);
 | 
| +  EXPECT_TRUE(handler.Init(&default_dict, &app_dict, &error));
 | 
| +  EXPECT_EQ(3U, handler.GetDictionarySize());
 | 
| +
 | 
| +  std::string result;
 | 
| +  EXPECT_TRUE(handler.GetMessage("n1", &result));
 | 
| +  EXPECT_EQ("message1 A B", result);
 | 
| +  EXPECT_TRUE(handler.GetMessage("n2", &result));
 | 
| +  EXPECT_EQ("message2 C", result);
 | 
| +  EXPECT_TRUE(handler.GetMessage("n3", &result));
 | 
| +  EXPECT_EQ("message3", result);
 | 
| +}
 | 
| +
 | 
| +TEST(ExtensionMessageHandler, InitAppDictConsultedFirst) {
 | 
| +  DictionaryValue default_dict;
 | 
| +  DictionaryValue app_dict;
 | 
| +  std::string error;
 | 
| +  ExtensionMessageHandler handler;
 | 
| +
 | 
| +  CreateGoodDictionary(&default_dict);
 | 
| +
 | 
| +  CreateGoodDictionary(&app_dict);
 | 
| +  // Flip placeholders in message of n1 tree.
 | 
| +  app_dict.SetString(L"n1.message", "message1 $b$ $a$");
 | 
| +  // Remove one message from app dict.
 | 
| +  app_dict.Remove(L"n2", NULL);
 | 
| +
 | 
| +  EXPECT_TRUE(handler.Init(&default_dict, &app_dict, &error));
 | 
| +  EXPECT_EQ(3U, handler.GetDictionarySize());
 | 
| +
 | 
| +  std::string result;
 | 
| +  EXPECT_TRUE(handler.GetMessage("n1", &result));
 | 
| +  EXPECT_EQ("message1 B A", result);
 | 
| +  EXPECT_TRUE(handler.GetMessage("n2", &result));
 | 
| +  EXPECT_EQ("message2 C", result);
 | 
| +  EXPECT_TRUE(handler.GetMessage("n3", &result));
 | 
| +  EXPECT_EQ("message3", result);
 | 
| +}
 | 
| +
 | 
| +TEST(ExtensionMessageHandler, InitBadAppDict) {
 | 
| +  DictionaryValue default_dict;
 | 
| +  DictionaryValue app_dict;
 | 
| +  std::string error;
 | 
| +  ExtensionMessageHandler handler;
 | 
| +
 | 
| +  CreateBadDictionary(&app_dict, INVALID_NAME);
 | 
| +  EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error));
 | 
| +  EXPECT_EQ("Name of a key \"n 5\" is invalid. Only ASCII [a-z], "
 | 
| +            "[A-Z], [0-9] and \"_\" are allowed.", error);
 | 
| +
 | 
| +  CreateBadDictionary(&app_dict, NAME_NOT_A_TREE);
 | 
| +  EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error));
 | 
| +  EXPECT_EQ("Not a valid tree for key n4.", error);
 | 
| +
 | 
| +  CreateBadDictionary(&app_dict, EMPTY_NAME_TREE);
 | 
| +  EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error));
 | 
| +  EXPECT_EQ("There is no \"message\" element for key n4.", error);
 | 
| +
 | 
| +  CreateBadDictionary(&app_dict, MISSING_MESSAGE);
 | 
| +  EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error));
 | 
| +  EXPECT_EQ("There is no \"message\" element for key n1.", error);
 | 
| +
 | 
| +  CreateBadDictionary(&app_dict, PLACEHOLDER_NOT_A_TREE);
 | 
| +  EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error));
 | 
| +  EXPECT_EQ("Not a valid \"placeholders\" element for key n1.", error);
 | 
| +
 | 
| +  CreateBadDictionary(&app_dict, EMPTY_PLACEHOLDER_TREE);
 | 
| +  EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error));
 | 
| +  EXPECT_EQ("Placeholder \"a\" is missing but used in a message n1.", error);
 | 
| +
 | 
| +  CreateBadDictionary(&app_dict, CONTENT_MISSING);
 | 
| +  EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error));
 | 
| +  EXPECT_EQ("Invalid \"content\" element for key n1.", error);
 | 
| +
 | 
| +  CreateBadDictionary(&app_dict, MESSAGE_PLACEHOLDER_DOESNT_MATCH);
 | 
| +  EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error));
 | 
| +  EXPECT_EQ("Placeholder \"a\" is missing but used in a message n1.", error);
 | 
| +}
 | 
| +
 | 
| +struct ReplaceVariables {
 | 
| +  const char* original;
 | 
| +  const char* result;
 | 
| +  const char* begin_delimiter;
 | 
| +  const char* end_delimiter;
 | 
| +  bool pass;
 | 
| +};
 | 
| +
 | 
| +TEST(ExtensionMessageHandler, ReplaceMessagesInText) {
 | 
| +  const char* kMessageBegin = ExtensionMessageHandler::kMessageBegin;
 | 
| +  const char* kMessageEnd = ExtensionMessageHandler::kMessageEnd;
 | 
| +  const char* kPlaceholderBegin = ExtensionMessageHandler::kPlaceholderBegin;
 | 
| +  const char* kPlaceholderEnd = ExtensionMessageHandler::kPlaceholderEnd;
 | 
| +
 | 
| +  static ReplaceVariables test_cases[] = {
 | 
| +    // Message replacement.
 | 
| +    { "This is __MSG_simple__ message", "This is simple message",
 | 
| +      kMessageBegin, kMessageEnd, true },
 | 
| +    { "This is __MSG_", "This is __MSG_",
 | 
| +      kMessageBegin, kMessageEnd, true },
 | 
| +    { "This is __MSG__simple__ message", "_simple",
 | 
| +      kMessageBegin, kMessageEnd, false },
 | 
| +    { "__MSG_long__", "A pretty long replacement",
 | 
| +      kMessageBegin, kMessageEnd, true },
 | 
| +    { "A __MSG_simple__MSG_ a", "A simpleMSG_ a",
 | 
| +      kMessageBegin, kMessageEnd, true },
 | 
| +    { "A __MSG_simple__MSG_long__", "A simpleMSG_long__",
 | 
| +      kMessageBegin, kMessageEnd, true },
 | 
| +    { "A __MSG_simple____MSG_long__", "A simpleA pretty long replacement",
 | 
| +      kMessageBegin, kMessageEnd, true },
 | 
| +    { "__MSG_d1g1ts_are_ok__", "I are d1g1t",
 | 
| +      kMessageBegin, kMessageEnd, true },
 | 
| +    // Placeholder replacement.
 | 
| +    { "This is $simple$ message", "This is simple message",
 | 
| +       kPlaceholderBegin, kPlaceholderEnd, true },
 | 
| +    { "This is $", "This is $",
 | 
| +       kPlaceholderBegin, kPlaceholderEnd, true },
 | 
| +    { "This is $$simple$ message", "This is $simple message",
 | 
| +       kPlaceholderBegin, kPlaceholderEnd, true },
 | 
| +    { "$long_v$", "A pretty long replacement",
 | 
| +       kPlaceholderBegin, kPlaceholderEnd, true },
 | 
| +    { "A $simple$$ a", "A simple$ a",
 | 
| +       kPlaceholderBegin, kPlaceholderEnd, true },
 | 
| +    { "A $simple$long_v$", "A simplelong_v$",
 | 
| +       kPlaceholderBegin, kPlaceholderEnd, true },
 | 
| +    { "A $simple$$long_v$", "A simpleA pretty long replacement",
 | 
| +       kPlaceholderBegin, kPlaceholderEnd, true },
 | 
| +    { "This is $bad name$", "This is $bad name$",
 | 
| +       kPlaceholderBegin, kPlaceholderEnd, true },
 | 
| +    { "This is $missing$", "missing",
 | 
| +       kPlaceholderBegin, kPlaceholderEnd, false },
 | 
| +  };
 | 
| +
 | 
| +  ExtensionMessageHandler::SSMap messages;
 | 
| +  messages.insert(std::make_pair("simple", "simple"));
 | 
| +  messages.insert(std::make_pair("long", "A pretty long replacement"));
 | 
| +  messages.insert(std::make_pair("long_v", "A pretty long replacement"));
 | 
| +  messages.insert(std::make_pair("bad name", "Doesn't matter"));
 | 
| +  messages.insert(std::make_pair("d1g1ts_are_ok", "I are d1g1t"));
 | 
| +
 | 
| +  ExtensionMessageHandler handler;
 | 
| +  for (size_t i = 0; i < arraysize(test_cases); ++i) {
 | 
| +    std::string text = test_cases[i].original;
 | 
| +    EXPECT_EQ(test_cases[i].pass,
 | 
| +              handler.ReplaceVariablesInString(messages,
 | 
| +                                               test_cases[i].begin_delimiter,
 | 
| +                                               test_cases[i].end_delimiter,
 | 
| +                                               &text));
 | 
| +    EXPECT_EQ(test_cases[i].result, text);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +}  // namespace
 | 
| 
 | 
| Property changes on: chrome\browser\extensions\extension_message_handler_unittest.cc
 | 
| ___________________________________________________________________
 | 
| Added: svn:eol-style
 | 
|    + LF
 | 
| 
 | 
| 
 |