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

Side by Side Diff: chrome/browser/extensions/user_script_master_unittest.cc

Issue 420543002: Declarative content scripts: Browser-side: per-extension shared memory regions (lazily loaded) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix nit and rebase from master Created 6 years, 4 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
« no previous file with comments | « chrome/browser/extensions/user_script_master.cc ('k') | chrome/chrome_browser_extensions.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "chrome/browser/extensions/user_script_master.h"
6
7 #include <string>
8
9 #include "base/file_util.h"
10 #include "base/files/file_path.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/path_service.h"
14 #include "base/strings/string_util.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "content/public/browser/notification_registrar.h"
18 #include "content/public/browser/notification_service.h"
19 #include "content/public/test/test_browser_thread.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using content::BrowserThread;
23 using extensions::URLPatternSet;
24
25 namespace {
26
27 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
28 int schemes = URLPattern::SCHEME_ALL;
29 extent->AddPattern(URLPattern(schemes, pattern));
30 }
31
32 }
33
34 namespace extensions {
35
36 // Test bringing up a master on a specific directory, putting a script
37 // in there, etc.
38
39 class UserScriptMasterTest : public testing::Test,
40 public content::NotificationObserver {
41 public:
42 UserScriptMasterTest() : shared_memory_(NULL) {
43 }
44
45 virtual void SetUp() {
46 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
47
48 // Register for all user script notifications.
49 registrar_.Add(this,
50 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
51 content::NotificationService::AllSources());
52
53 // UserScriptMaster posts tasks to the file thread so make the current
54 // thread look like one.
55 file_thread_.reset(new content::TestBrowserThread(
56 BrowserThread::FILE, base::MessageLoop::current()));
57 ui_thread_.reset(new content::TestBrowserThread(
58 BrowserThread::UI, base::MessageLoop::current()));
59 }
60
61 virtual void TearDown() {
62 file_thread_.reset();
63 ui_thread_.reset();
64 }
65
66 virtual void Observe(int type,
67 const content::NotificationSource& source,
68 const content::NotificationDetails& details) OVERRIDE {
69 DCHECK(type == extensions::NOTIFICATION_USER_SCRIPTS_UPDATED);
70
71 shared_memory_ = content::Details<base::SharedMemory>(details).ptr();
72 if (base::MessageLoop::current() == &message_loop_)
73 base::MessageLoop::current()->Quit();
74 }
75
76 // Directory containing user scripts.
77 base::ScopedTempDir temp_dir_;
78
79 content::NotificationRegistrar registrar_;
80
81 // MessageLoop used in tests.
82 base::MessageLoopForUI message_loop_;
83
84 scoped_ptr<content::TestBrowserThread> file_thread_;
85 scoped_ptr<content::TestBrowserThread> ui_thread_;
86
87 // Updated to the script shared memory when we get notified.
88 base::SharedMemory* shared_memory_;
89 };
90
91 // Test that we get notified even when there are no scripts.
92 TEST_F(UserScriptMasterTest, NoScripts) {
93 TestingProfile profile;
94 UserScriptMaster master(&profile);
95 master.StartLoad();
96 message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
97 message_loop_.Run();
98
99 ASSERT_TRUE(shared_memory_ != NULL);
100 }
101
102 TEST_F(UserScriptMasterTest, Parse1) {
103 const std::string text(
104 "// This is my awesome script\n"
105 "// It does stuff.\n"
106 "// ==UserScript== trailing garbage\n"
107 "// @name foobar script\n"
108 "// @namespace http://www.google.com/\n"
109 "// @include *mail.google.com*\n"
110 "// \n"
111 "// @othergarbage\n"
112 "// @include *mail.yahoo.com*\r\n"
113 "// @include \t *mail.msn.com*\n" // extra spaces after "@include" OK
114 "//@include not-recognized\n" // must have one space after "//"
115 "// ==/UserScript== trailing garbage\n"
116 "\n"
117 "\n"
118 "alert('hoo!');\n");
119
120 UserScript script;
121 EXPECT_TRUE(UserScriptMaster::ParseMetadataHeader(text, &script));
122 ASSERT_EQ(3U, script.globs().size());
123 EXPECT_EQ("*mail.google.com*", script.globs()[0]);
124 EXPECT_EQ("*mail.yahoo.com*", script.globs()[1]);
125 EXPECT_EQ("*mail.msn.com*", script.globs()[2]);
126 }
127
128 TEST_F(UserScriptMasterTest, Parse2) {
129 const std::string text("default to @include *");
130
131 UserScript script;
132 EXPECT_TRUE(UserScriptMaster::ParseMetadataHeader(text, &script));
133 ASSERT_EQ(1U, script.globs().size());
134 EXPECT_EQ("*", script.globs()[0]);
135 }
136
137 TEST_F(UserScriptMasterTest, Parse3) {
138 const std::string text(
139 "// ==UserScript==\n"
140 "// @include *foo*\n"
141 "// ==/UserScript=="); // no trailing newline
142
143 UserScript script;
144 UserScriptMaster::ParseMetadataHeader(text, &script);
145 ASSERT_EQ(1U, script.globs().size());
146 EXPECT_EQ("*foo*", script.globs()[0]);
147 }
148
149 TEST_F(UserScriptMasterTest, Parse4) {
150 const std::string text(
151 "// ==UserScript==\n"
152 "// @match http://*.mail.google.com/*\n"
153 "// @match \t http://mail.yahoo.com/*\n"
154 "// ==/UserScript==\n");
155
156 URLPatternSet expected_patterns;
157 AddPattern(&expected_patterns, "http://*.mail.google.com/*");
158 AddPattern(&expected_patterns, "http://mail.yahoo.com/*");
159
160 UserScript script;
161 EXPECT_TRUE(UserScriptMaster::ParseMetadataHeader(text, &script));
162 EXPECT_EQ(0U, script.globs().size());
163 EXPECT_EQ(expected_patterns, script.url_patterns());
164 }
165
166 TEST_F(UserScriptMasterTest, Parse5) {
167 const std::string text(
168 "// ==UserScript==\n"
169 "// @match http://*mail.google.com/*\n"
170 "// ==/UserScript==\n");
171
172 // Invalid @match value.
173 UserScript script;
174 EXPECT_FALSE(UserScriptMaster::ParseMetadataHeader(text, &script));
175 }
176
177 TEST_F(UserScriptMasterTest, Parse6) {
178 const std::string text(
179 "// ==UserScript==\n"
180 "// @include http://*.mail.google.com/*\n"
181 "// @match \t http://mail.yahoo.com/*\n"
182 "// ==/UserScript==\n");
183
184 // Allowed to match @include and @match.
185 UserScript script;
186 EXPECT_TRUE(UserScriptMaster::ParseMetadataHeader(text, &script));
187 }
188
189 TEST_F(UserScriptMasterTest, Parse7) {
190 // Greasemonkey allows there to be any leading text before the comment marker.
191 const std::string text(
192 "// ==UserScript==\n"
193 "adsasdfasf// @name hello\n"
194 " // @description\twiggity woo\n"
195 "\t// @match \t http://mail.yahoo.com/*\n"
196 "// ==/UserScript==\n");
197
198 UserScript script;
199 EXPECT_TRUE(UserScriptMaster::ParseMetadataHeader(text, &script));
200 ASSERT_EQ("hello", script.name());
201 ASSERT_EQ("wiggity woo", script.description());
202 ASSERT_EQ(1U, script.url_patterns().patterns().size());
203 EXPECT_EQ("http://mail.yahoo.com/*",
204 script.url_patterns().begin()->GetAsString());
205 }
206
207 TEST_F(UserScriptMasterTest, Parse8) {
208 const std::string text(
209 "// ==UserScript==\n"
210 "// @name myscript\n"
211 "// @match http://www.google.com/*\n"
212 "// @exclude_match http://www.google.com/foo*\n"
213 "// ==/UserScript==\n");
214
215 UserScript script;
216 EXPECT_TRUE(UserScriptMaster::ParseMetadataHeader(text, &script));
217 ASSERT_EQ("myscript", script.name());
218 ASSERT_EQ(1U, script.url_patterns().patterns().size());
219 EXPECT_EQ("http://www.google.com/*",
220 script.url_patterns().begin()->GetAsString());
221 ASSERT_EQ(1U, script.exclude_url_patterns().patterns().size());
222 EXPECT_EQ("http://www.google.com/foo*",
223 script.exclude_url_patterns().begin()->GetAsString());
224 }
225
226 TEST_F(UserScriptMasterTest, SkipBOMAtTheBeginning) {
227 base::FilePath path = temp_dir_.path().AppendASCII("script.user.js");
228 const std::string content("\xEF\xBB\xBF alert('hello');");
229 size_t written = base::WriteFile(path, content.c_str(), content.size());
230 ASSERT_EQ(written, content.size());
231
232 UserScript user_script;
233 user_script.js_scripts().push_back(UserScript::File(
234 temp_dir_.path(), path.BaseName(), GURL()));
235
236 UserScriptList user_scripts;
237 user_scripts.push_back(user_script);
238
239 UserScriptMaster::LoadScriptsForTest(&user_scripts);
240
241 EXPECT_EQ(content.substr(3),
242 user_scripts[0].js_scripts()[0].GetContent().as_string());
243 }
244
245 TEST_F(UserScriptMasterTest, LeaveBOMNotAtTheBeginning) {
246 base::FilePath path = temp_dir_.path().AppendASCII("script.user.js");
247 const std::string content("alert('here's a BOOM: \xEF\xBB\xBF');");
248 size_t written = base::WriteFile(path, content.c_str(), content.size());
249 ASSERT_EQ(written, content.size());
250
251 UserScript user_script;
252 user_script.js_scripts().push_back(UserScript::File(
253 temp_dir_.path(), path.BaseName(), GURL()));
254
255 UserScriptList user_scripts;
256 user_scripts.push_back(user_script);
257
258 UserScriptMaster::LoadScriptsForTest(&user_scripts);
259
260 EXPECT_EQ(content, user_scripts[0].js_scripts()[0].GetContent().as_string());
261 }
262
263 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/user_script_master.cc ('k') | chrome/chrome_browser_extensions.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698