Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Side by Side Diff: chrome/common/extensions/manifest_handler_unittest.cc

Issue 12091115: Allow manifest handlers to declare keys they depend on that must be parsed before them. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 <string>
6 #include <vector>
7
8 #include "base/file_path.h"
9 #include "base/stl_util.h"
10 #include "base/utf_string_conversions.h"
11 #include "chrome/common/extensions/extension.h"
12 #include "chrome/common/extensions/extension_builder.h"
13 #include "chrome/common/extensions/manifest_handler.h"
14 #include "chrome/common/extensions/value_builder.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace extensions {
18
19 class ManifestHandlerTest : public testing::Test {
20 public:
21 class ParsingWatcher {
22 public:
23 // Called when a manifest handler parses.
24 void Record(std::string name) {
Devlin 2013/02/02 21:41:38 const & string?
25 parsed_names_.push_back(name);
26 }
27
28 const std::vector<std::string>& parsed_names() {
29 return parsed_names_;
30 }
31
32 // Returns true if |name_before| was parsed before |name_after|.
33 bool ParsedBefore(std::string name_before, std::string name_after) {
Devlin 2013/02/02 21:41:38 const & strings?
34 size_t i_before = parsed_names_.size();
35 size_t i_after = 0;
36 for (size_t i = 0; i < parsed_names_.size(); ++i) {
37 if (parsed_names_[i] == name_before)
38 i_before = i;
39 if (parsed_names_[i] == name_after)
40 i_after = i;
41 }
42 if (i_before < i_after)
43 return true;
44 return false;
45 }
46
47 private:
48 // The order of manifest handlers that we watched parsing.
49 std::vector<std::string> parsed_names_;
Devlin 2013/02/02 21:41:38 If we only care about relative ordering, this migh
Yoyo Zhou 2013/02/04 20:24:31 If only STL had a sensible behavior for when the k
50 };
51
52 class TestManifestHandler : public ManifestHandler {
53 public:
54 TestManifestHandler(const std::string& name,
55 const std::vector<std::string> prereqs,
Devlin 2013/02/02 21:41:38 const & vector?
Yoyo Zhou 2013/02/04 20:24:31 How did I miss that.
56 ParsingWatcher* watcher)
57 : name_(name), prereqs_(prereqs), watcher_(watcher) {
58 }
59
60 virtual bool Parse(Extension* extension, string16* error) OVERRIDE {
61 watcher_->Record(name_);
62 return true;
63 }
64
65 virtual const std::vector<std::string>& PrerequisiteKeys() OVERRIDE {
66 return prereqs_;
67 }
68
69 std::string name_;
Devlin 2013/02/02 21:41:38 Trailing underscore and use suggests these should
Yoyo Zhou 2013/02/04 20:24:31 Made protected so the subclasses can refer to them
70 std::vector<std::string> prereqs_;
71 ParsingWatcher* watcher_;
72 };
73
74 class FailingTestManifestHandler : public TestManifestHandler {
75 public:
76 FailingTestManifestHandler(const std::string& name,
77 const std::vector<std::string> prereqs,
78 ParsingWatcher* watcher)
79 : TestManifestHandler(name, prereqs, watcher) {
80 }
81 virtual bool Parse(Extension* extension, string16* error) OVERRIDE {
82 *error = ASCIIToUTF16(name_);
83 return false;
84 }
85 };
86
87 class AlwaysParseTestManifestHandler : public TestManifestHandler {
88 public:
89 AlwaysParseTestManifestHandler(const std::string& name,
90 const std::vector<std::string> prereqs,
91 ParsingWatcher* watcher)
92 : TestManifestHandler(name, prereqs, watcher) {
93 }
94
95 virtual bool AlwaysParseForType(Manifest::Type type) OVERRIDE {
96 return true;
97 }
98 };
99
100 protected:
101 virtual void SetUp() OVERRIDE {
102 ManifestHandler::ClearRegistryForTesting();
103 }
104 };
105
106 TEST_F(ManifestHandlerTest, DependentHandlers) {
107 ParsingWatcher watcher;
108 std::vector<std::string> prereqs;
109 ManifestHandler::Register(
110 "a", make_linked_ptr(new TestManifestHandler("A", prereqs, &watcher)));
111 ManifestHandler::Register(
112 "b", make_linked_ptr(new TestManifestHandler("B", prereqs, &watcher)));
113 ManifestHandler::Register(
114 "j", make_linked_ptr(new TestManifestHandler("J", prereqs, &watcher)));
115 ManifestHandler::Register(
116 "k", make_linked_ptr(
117 new AlwaysParseTestManifestHandler("K", prereqs, &watcher)));
118 prereqs.push_back("c.d");
119 linked_ptr<TestManifestHandler> handler_c2(
120 new TestManifestHandler("C.EZ", prereqs, &watcher));
121 ManifestHandler::Register("c.e", handler_c2);
122 ManifestHandler::Register("c.z", handler_c2);
123 prereqs.clear();
124 prereqs.push_back("b");
125 prereqs.push_back("k");
126 ManifestHandler::Register(
127 "c.d", make_linked_ptr(new TestManifestHandler(
128 "C.D", prereqs, &watcher)));
129
130 scoped_refptr<Extension> extension = ExtensionBuilder()
131 .SetManifest(DictionaryBuilder()
132 .Set("name", "no name")
133 .Set("version", "0")
134 .Set("manifest_version", 2)
135 .Set("a", 1)
136 .Set("b", 2)
137 .Set("c", DictionaryBuilder()
138 .Set("d", 3)
139 .Set("e", 4)
140 .Set("f", 5))
141 .Set("g", 6))
142 .Build();
143
144 // A, B, C.EZ, C.D, K
145 EXPECT_EQ(5u, watcher.parsed_names().size());
146 EXPECT_TRUE(watcher.ParsedBefore("B", "C.D"));
147 EXPECT_TRUE(watcher.ParsedBefore("K", "C.D"));
148 EXPECT_TRUE(watcher.ParsedBefore("C.D", "C.EZ"));
149 }
150
151 TEST_F(ManifestHandlerTest, FailingHandlers) {
152 // Can't use ExtensionBuilder, because this extension will fail to
153 // be parsed.
154 scoped_ptr<base::DictionaryValue> manifest_a(
155 DictionaryBuilder()
156 .Set("name", "no name")
157 .Set("version", "0")
158 .Set("manifest_version", 2)
159 .Set("a", 1)
160 .Build());
161
162 // Succeeds when "a" is not recognized.
163 std::string error;
164 scoped_refptr<Extension> extension = Extension::Create(
165 FilePath(),
166 Manifest::INVALID_LOCATION,
167 *manifest_a,
168 Extension::NO_FLAGS,
169 &error);
170 EXPECT_TRUE(extension);
171
172 // Register a handler for "a" that fails.
173 ParsingWatcher watcher;
174 ManifestHandler::Register(
175 "a", make_linked_ptr(new FailingTestManifestHandler(
176 "A", std::vector<std::string>(), &watcher)));
177
178 extension = Extension::Create(
179 FilePath(),
180 Manifest::INVALID_LOCATION,
181 *manifest_a,
182 Extension::NO_FLAGS,
183 &error);
184 EXPECT_FALSE(extension);
185 EXPECT_EQ("A", error);
186 }
187
188 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698