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.
8 #include "base/files/file_path.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/stl_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "xwalk/application/common/application_data.h"
13 #include "xwalk/application/common/manifest_handler.h"
14 #include "testing/gtest/include/gtest/gtest.h"
17 namespace application {
21 std::vector<std::string> SingleKey(const std::string& key) {
22 return std::vector<std::string>(1, key);
27 class ScopedTestingManifestHandlerRegistry {
29 ScopedTestingManifestHandlerRegistry(
30 const std::vector<ManifestHandler*>& handlers)
32 new ManifestHandlerRegistry(handlers)),
34 ManifestHandlerRegistry::GetInstance(Package::XPK)) {
35 ManifestHandlerRegistry::SetInstanceForTesting(
36 registry_.get(), Package::XPK);
39 ~ScopedTestingManifestHandlerRegistry() {
40 ManifestHandlerRegistry::SetInstanceForTesting(
41 prev_registry_, Package::XPK);
44 scoped_ptr<ManifestHandlerRegistry> registry_;
45 ManifestHandlerRegistry* prev_registry_;
48 class ManifestHandlerTest : public testing::Test {
50 class ParsingWatcher {
52 // Called when a manifest handler parses.
53 void Record(const std::string& name) {
54 parsed_names_.push_back(name);
57 const std::vector<std::string>& parsed_names() {
61 // Returns true if |name_before| was parsed before |name_after|.
62 bool ParsedBefore(const std::string& name_before,
63 const std::string& name_after) {
64 size_t prev_iterator = parsed_names_.size();
65 size_t next_iterator = 0;
66 for (size_t i = 0; i < parsed_names_.size(); ++i) {
67 if (parsed_names_[i] == name_before)
69 if (parsed_names_[i] == name_after)
73 if (prev_iterator < next_iterator)
80 // The order of manifest handlers that we watched parsing.
81 std::vector<std::string> parsed_names_;
84 class TestManifestHandler : public ManifestHandler {
86 TestManifestHandler(const std::string& name,
87 const std::vector<std::string>& keys,
88 const std::vector<std::string>& prereqs,
89 ParsingWatcher* watcher)
90 : name_(name), keys_(keys), prereqs_(prereqs), watcher_(watcher) {
93 virtual ~TestManifestHandler() {}
96 scoped_refptr<ApplicationData> application,
97 base::string16* error) OVERRIDE {
98 watcher_->Record(name_);
102 virtual std::vector<std::string> PrerequisiteKeys() const OVERRIDE {
106 virtual std::vector<std::string> Keys() const OVERRIDE {
112 std::vector<std::string> keys_;
113 std::vector<std::string> prereqs_;
114 ParsingWatcher* watcher_;
117 class FailingTestManifestHandler : public TestManifestHandler {
119 FailingTestManifestHandler(const std::string& name,
120 const std::vector<std::string>& keys,
121 const std::vector<std::string>& prereqs,
122 ParsingWatcher* watcher)
123 : TestManifestHandler(name, keys, prereqs, watcher) {
126 scoped_refptr<ApplicationData> application,
127 base::string16* error) OVERRIDE {
128 *error = base::ASCIIToUTF16(name_);
133 class AlwaysParseTestManifestHandler : public TestManifestHandler {
135 AlwaysParseTestManifestHandler(const std::string& name,
136 const std::vector<std::string>& keys,
137 const std::vector<std::string>& prereqs,
138 ParsingWatcher* watcher)
139 : TestManifestHandler(name, keys, prereqs, watcher) {
142 virtual bool AlwaysParseForType(Manifest::Type type) const OVERRIDE {
147 class TestManifestValidator : public ManifestHandler {
149 TestManifestValidator(bool return_value,
150 bool always_validate,
151 std::vector<std::string> keys)
152 : return_value_(return_value),
153 always_validate_(always_validate),
158 scoped_refptr<ApplicationData> application,
159 base::string16* error) OVERRIDE {
163 virtual bool Validate(
164 scoped_refptr<const ApplicationData> application,
165 std::string* error) const OVERRIDE {
166 return return_value_;
169 virtual bool AlwaysValidateForType(Manifest::Type type) const OVERRIDE {
170 return always_validate_;
173 virtual std::vector<std::string> Keys() const OVERRIDE {
179 bool always_validate_;
180 std::vector<std::string> keys_;
184 TEST_F(ManifestHandlerTest, DependentHandlers) {
185 std::vector<ManifestHandler*> handlers;
186 ParsingWatcher watcher;
187 std::vector<std::string> prereqs;
189 new TestManifestHandler("A", SingleKey("a"), prereqs, &watcher));
191 new TestManifestHandler("B", SingleKey("b"), prereqs, &watcher));
193 new TestManifestHandler("J", SingleKey("j"), prereqs, &watcher));
195 new AlwaysParseTestManifestHandler(
196 "K", SingleKey("k"), prereqs, &watcher));
197 prereqs.push_back("c.d");
198 std::vector<std::string> keys;
199 keys.push_back("c.e");
200 keys.push_back("c.z");
202 new TestManifestHandler("C.EZ", keys, prereqs, &watcher));
204 prereqs.push_back("b");
205 prereqs.push_back("k");
207 new TestManifestHandler("C.D", SingleKey("c.d"), prereqs, &watcher));
208 ScopedTestingManifestHandlerRegistry registry(handlers);
210 base::DictionaryValue manifest;
211 manifest.SetString("name", "no name");
212 manifest.SetString("version", "0");
213 manifest.SetInteger("manifest_version", 2);
214 manifest.SetInteger("a", 1);
215 manifest.SetInteger("b", 2);
216 manifest.SetInteger("c.d", 3);
217 manifest.SetInteger("c.e", 4);
218 manifest.SetInteger("c.f", 5);
219 manifest.SetInteger("g", 6);
221 scoped_refptr<ApplicationData> application = ApplicationData::Create(
223 Manifest::INVALID_TYPE,
227 EXPECT_TRUE(application.get());
228 // A, B, C.EZ, C.D, K
229 EXPECT_EQ(5u, watcher.parsed_names().size());
230 EXPECT_TRUE(watcher.ParsedBefore("B", "C.D"));
231 EXPECT_TRUE(watcher.ParsedBefore("K", "C.D"));
232 EXPECT_TRUE(watcher.ParsedBefore("C.D", "C.EZ"));
235 TEST_F(ManifestHandlerTest, FailingHandlers) {
236 scoped_ptr<ScopedTestingManifestHandlerRegistry> registry(
237 new ScopedTestingManifestHandlerRegistry(
238 std::vector<ManifestHandler*>()));
239 // Can't use ApplicationBuilder, because this application will fail to
241 base::DictionaryValue manifest_a;
242 manifest_a.SetString("name", "no name");
243 manifest_a.SetString("version", "0");
244 manifest_a.SetInteger("manifest_version", 2);
245 manifest_a.SetInteger("a", 1);
247 // Succeeds when "a" is not recognized.
249 scoped_refptr<ApplicationData> application = ApplicationData::Create(
251 Manifest::INVALID_TYPE,
255 EXPECT_TRUE(application.get());
257 // Register a handler for "a" that fails.
258 std::vector<ManifestHandler*> handlers;
259 ParsingWatcher watcher;
261 new FailingTestManifestHandler(
262 "A", SingleKey("a"), std::vector<std::string>(), &watcher));
264 registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
266 application = ApplicationData::Create(
268 Manifest::INVALID_TYPE,
272 EXPECT_FALSE(application.get());
273 EXPECT_EQ("A", error);
276 TEST_F(ManifestHandlerTest, Validate) {
277 scoped_ptr<ScopedTestingManifestHandlerRegistry> registry(
278 new ScopedTestingManifestHandlerRegistry(
279 std::vector<ManifestHandler*>()));
280 base::DictionaryValue manifest;
281 manifest.SetString("name", "no name");
282 manifest.SetString("version", "0");
283 manifest.SetInteger("manifest_version", 2);
284 manifest.SetInteger("a", 1);
285 manifest.SetInteger("b", 2);
287 scoped_refptr<ApplicationData> application = ApplicationData::Create(
289 Manifest::COMMAND_LINE,
293 EXPECT_TRUE(application.get());
295 std::vector<ManifestHandler*> handlers;
296 // Always validates and fails.
298 new TestManifestValidator(false, true, SingleKey("c")));
300 registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
302 registry->registry_->ValidateAppManifest(application, &error));
305 new TestManifestValidator(false, false, SingleKey("c")));
307 registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
309 registry->registry_->ValidateAppManifest(application, &error));
311 // Validates "a" and fails.
313 (new TestManifestValidator(false, true, SingleKey("a")));
315 registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
317 registry->registry_->ValidateAppManifest(application, &error));
320 } // namespace application