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

Side by Side Diff: chrome/test/data/webui/settings/prefs_tests.js

Issue 1357183002: MD-Settings: convert cr-settings-prefs to a singleton model (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: clarify singleton/private/model language Created 5 years, 3 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/resources/settings/prefs/prefs_types.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** @fileoverview Suite of tests for cr-settings-prefs. */ 5 /** @fileoverview Suite of tests for cr-settings-prefs. */
6 cr.define('cr_settings_prefs', function() { 6 cr.define('cr_settings_prefs', function() {
7 /** 7 /**
8 * Creates a deep copy of the object. 8 * Creates a deep copy of the object.
9 * @param {!Object} obj 9 * @param {!Object} obj
10 * @return {!Object} 10 * @return {!Object}
11 */ 11 */
12 function deepCopy(obj) { 12 function deepCopy(obj) {
13 return JSON.parse(JSON.stringify(obj)); 13 return JSON.parse(JSON.stringify(obj));
14 } 14 }
15 15
16 /** 16 /**
17 * Mock of chrome.settingsPrivate API. 17 * Mock of chrome.settingsPrivate API.
18 * @constructor 18 * @constructor
19 * @extends {chrome.settingsPrivate} 19 * @extends {chrome.settingsPrivate}
20 */ 20 */
21 function MockSettingsApi() { 21 function MockSettingsApi() {
22 this.prefs = {}; 22 this.prefs = {};
23 this.listener_ = null;
24 23
25 // Hack alert: bind this instance's onPrefsChanged members to this. 24 // Hack alert: bind this instance's onPrefsChanged members to this.
26 this.onPrefsChanged = { 25 this.onPrefsChanged = {
27 addListener: this.onPrefsChanged.addListener.bind(this), 26 addListener: this.onPrefsChanged.addListener.bind(this),
28 removeListener: this.onPrefsChanged.removeListener.bind(this), 27 removeListener: this.onPrefsChanged.removeListener.bind(this),
29 }; 28 };
30 29
31 for (var testCase of prefsTestCases) 30 for (var testCase of prefsTestCases)
32 this.addPref_(testCase.type, testCase.key, testCase.values[0]); 31 this.addPref_(testCase.type, testCase.key, testCase.values[0]);
33 } 32 }
34 33
34 // Make the listener static because it refers to a singleton.
35 MockSettingsApi.listener_ = null;
36
35 MockSettingsApi.prototype = { 37 MockSettingsApi.prototype = {
36 // chrome.settingsPrivate overrides. 38 // chrome.settingsPrivate overrides.
37 onPrefsChanged: { 39 onPrefsChanged: {
38 addListener: function(listener) { 40 addListener: function(listener) {
39 this.listener_ = listener; 41 MockSettingsApi.listener_ = listener;
40 }, 42 },
41 43
42 removeListener: function(listener) { 44 removeListener: function(listener) {
43 expectNotEquals(null, this.listener_); 45 MockSettingsApi.listener_ = null;
44 this.listener_ = null;
45 }, 46 },
46 }, 47 },
47 48
48 getAllPrefs: function(callback) { 49 getAllPrefs: function(callback) {
49 // Send a copy of prefs to keep our internal state private. 50 // Send a copy of prefs to keep our internal state private.
50 var prefs = []; 51 var prefs = [];
51 for (var key in this.prefs) 52 for (var key in this.prefs)
52 prefs.push(deepCopy(this.prefs[key])); 53 prefs.push(deepCopy(this.prefs[key]));
53 54
54 callback(prefs); 55 // Run the callback asynchronously to test that the prefs aren't actually
56 // used before they become available.
57 setTimeout(callback.bind(null, prefs));
55 }, 58 },
56 59
57 setPref: function(key, value, pageId, callback) { 60 setPref: function(key, value, pageId, callback) {
58 var pref = this.prefs[key]; 61 var pref = this.prefs[key];
59 assertNotEquals(undefined, pref); 62 assertNotEquals(undefined, pref);
60 assertEquals(typeof value, typeof pref.value); 63 assertEquals(typeof value, typeof pref.value);
61 assertEquals(Array.isArray(value), Array.isArray(pref.value)); 64 assertEquals(Array.isArray(value), Array.isArray(pref.value));
62 65
63 if (this.failNextSetPref_) { 66 if (this.failNextSetPref_) {
64 callback(false); 67 callback(false);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 * @param {!Object<{key: string, value: *}>} changes 106 * @param {!Object<{key: string, value: *}>} changes
104 */ 107 */
105 sendPrefChanges: function(changes) { 108 sendPrefChanges: function(changes) {
106 var prefs = []; 109 var prefs = [];
107 for (var change of changes) { 110 for (var change of changes) {
108 var pref = this.prefs[change.key]; 111 var pref = this.prefs[change.key];
109 assertNotEquals(undefined, pref); 112 assertNotEquals(undefined, pref);
110 pref.value = change.value; 113 pref.value = change.value;
111 prefs.push(deepCopy(pref)); 114 prefs.push(deepCopy(pref));
112 } 115 }
113 this.listener_(prefs); 116 MockSettingsApi.listener_(prefs);
114 }, 117 },
115 118
116 // Private methods for use by the mock API. 119 // Private methods for use by the mock API.
117 120
118 /** 121 /**
119 * @param {!chrome.settingsPrivate.PrefType} type 122 * @param {!chrome.settingsPrivate.PrefType} type
120 * @param {string} key 123 * @param {string} key
121 * @param {*} value 124 * @param {*} value
122 */ 125 */
123 addPref_: function(type, key, value) { 126 addPref_: function(type, key, value) {
124 this.prefs[key] = { 127 this.prefs[key] = {
125 type: type, 128 type: type,
126 key: key, 129 key: key,
127 value: value, 130 value: value,
128 }; 131 };
129 }, 132 },
130 }; 133 };
131 134
132 function registerTests() { 135 function registerTests() {
133 suite('CrSettingsPrefs', function() { 136 suite('CrSettingsPrefs', function() {
134 /** 137 /**
135 * Prefs instance created before each test. 138 * Prefs instance created before each test.
136 * @type {CrSettingsPrefs} 139 * @type {CrSettingsPrefsElement|undefined}
137 */ 140 */
138 var prefs; 141 var prefs;
139 142
140 /** @type {MockSettingsApi} */ 143 /** @type {MockSettingsApi} */
141 var mockApi = null; 144 var mockApi = null;
142 145
143 /** 146 /**
144 * @param {!Object} prefStore Pref store from <cr-settings-prefs>. 147 * @param {!Object} prefStore Pref store from <cr-settings-prefs>.
145 * @param {string} key Pref key of the pref to return. 148 * @param {string} key Pref key of the pref to return.
146 * @return {(chrome.settingsPrivate.PrefObject|undefined)} 149 * @return {chrome.settingsPrivate.PrefObject|undefined}
147 */ 150 */
148 function getPrefFromKey(prefStore, key) { 151 function getPrefFromKey(prefStore, key) {
149 var path = key.split('.'); 152 var path = key.split('.');
150 var pref = prefStore; 153 var pref = prefStore;
151 for (var part of path) { 154 for (var part of path) {
152 pref = pref[part]; 155 pref = pref[part];
153 if (!pref) 156 if (!pref)
154 return undefined; 157 return undefined;
155 } 158 }
156 return pref; 159 return pref;
157 } 160 }
158 161
159 /** 162 /**
160 * Checks that the mock API pref store contains the expected values. 163 * Checks that the mock API pref store contains the expected values.
161 * @param {number} testCaseValueIndex The index of possible values from 164 * @param {number} testCaseValueIndex The index of possible values from
162 * the test case to check. 165 * the test case to check.
163 */ 166 */
164 function expectMockApiPrefsSet(testCaseValueIndex) { 167 function assertMockApiPrefsSet(testCaseValueIndex) {
165 for (var testCase of prefsTestCases) { 168 for (var testCase of prefsTestCases) {
166 var expectedValue = JSON.stringify( 169 var expectedValue = JSON.stringify(
167 testCase.values[testCaseValueIndex]); 170 testCase.values[testCaseValueIndex]);
168 var actualValue = JSON.stringify(mockApi.prefs[testCase.key].value); 171 var actualValue = JSON.stringify(mockApi.prefs[testCase.key].value);
169 expectEquals(expectedValue, actualValue); 172 assertEquals(expectedValue, actualValue);
170 } 173 }
171 } 174 }
172 175
173 /** 176 /**
174 * Checks that the <cr-settings-prefs> contains the expected values. 177 * Checks that the <cr-settings-prefs> contains the expected values.
175 * @param {number} testCaseValueIndex The index of possible values from 178 * @param {number} testCaseValueIndex The index of possible values from
176 * the test case to check. 179 * the test case to check.
177 */ 180 */
178 function expectPrefsSet(testCaseValueIndex) { 181 function assertPrefsSet(testCaseValueIndex) {
179 for (var testCase of prefsTestCases) { 182 for (var testCase of prefsTestCases) {
180 var expectedValue = JSON.stringify( 183 var expectedValue = JSON.stringify(
181 testCase.values[testCaseValueIndex]); 184 testCase.values[testCaseValueIndex]);
182 var actualValue = JSON.stringify( 185 var actualValue = JSON.stringify(
183 prefs.get('prefs.' + testCase.key + '.value')); 186 prefs.get('prefs.' + testCase.key + '.value'));
184 expectEquals(expectedValue, actualValue); 187 assertEquals(expectedValue, actualValue);
185 } 188 }
186 } 189 }
187 190
188 // Initialize a <cr-settings-prefs> element before each test. 191 /**
189 setup(function(done) { 192 * List of CrSettingsPref elements created for testing.
193 * @type {!Array<!CrSettingsPrefs>}
194 */
195 var createdElements = [];
196
197 // Initialize <cr-settings-prefs> elements before each test.
198 setup(function() {
190 mockApi = new MockSettingsApi(); 199 mockApi = new MockSettingsApi();
191 // TODO(michaelpg): don't use global variables to inject the API. 200 // TODO(michaelpg): don't use global variables to inject the API.
192 window.mockApi = mockApi; 201 window.mockApi = mockApi;
193 202
194 // Create and attach the <cr-settings-prefs> element. 203 // Create and attach the <cr-settings-prefs> elements. Make several of
204 // them to test that the shared state model scales correctly.
205 createdElements = [];
206 for (var i = 0; i < 100; i++) {
207 var prefsInstance = document.createElement('cr-settings-prefs');
208 document.body.appendChild(prefsInstance);
209 createdElements.push(prefsInstance);
210 }
211 // For simplicity, only use one prefs element in the tests. Use an
212 // arbitrary index instead of the first or last element created.
213 prefs = createdElements[42];
214
215 // getAllPrefs is asynchronous, so return the prefs promise.
216 return CrSettingsPrefs.initialized;
217 });
218
219 teardown(function() {
220 CrSettingsPrefs.resetForTesting();
221
222 // Reset each <cr-settings-prefs>.
223 for (var i = 0; i < createdElements.length; i++)
224 createdElements[i].resetForTesting();
225
195 PolymerTest.clearBody(); 226 PolymerTest.clearBody();
196 prefs = document.createElement('cr-settings-prefs');
197 document.body.appendChild(prefs);
198
199 window.mockApi = undefined; 227 window.mockApi = undefined;
200
201 // Wait for CrSettingsPrefs.INITIALIZED.
202 if (!CrSettingsPrefs.isInitialized) {
203 var listener = function() {
204 document.removeEventListener(CrSettingsPrefs.INITIALIZED, listener);
205 done();
206 };
207 document.addEventListener(CrSettingsPrefs.INITIALIZED, listener);
208 return;
209 }
210
211 done();
212 }); 228 });
213 229
214 test('receives and caches prefs', function() { 230 test('receives and caches prefs', function() {
215 // Test that each pref has been successfully copied to the Polymer 231 // Test that each pref has been successfully copied to the Polymer
216 // |prefs| property. 232 // |prefs| property.
217 for (var key in mockApi.prefs) { 233 for (var key in mockApi.prefs) {
218 var expectedPref = mockApi.prefs[key]; 234 var expectedPref = mockApi.prefs[key];
219 var actualPref = getPrefFromKey(prefs.prefs, key); 235 var actualPref = getPrefFromKey(prefs.prefs, key);
220 if (!expectNotEquals(undefined, actualPref)) { 236 if (!expectNotEquals(undefined, actualPref)) {
221 // We've already registered an error, so skip the pref. 237 // We've already registered an error, so skip the pref.
222 continue; 238 continue;
223 } 239 }
224 240
225 expectEquals(JSON.stringify(expectedPref), 241 assertEquals(JSON.stringify(expectedPref),
226 JSON.stringify(actualPref)); 242 JSON.stringify(actualPref));
227 } 243 }
228 }); 244 });
229 245
230 test('forwards pref changes to API', function() { 246 test('forwards pref changes to API', function() {
231 // Test that cr-settings-prefs uses the setPref API. 247 // Test that cr-settings-prefs uses the setPref API.
232 for (var testCase of prefsTestCases) { 248 for (var testCase of prefsTestCases) {
233 prefs.set('prefs.' + testCase.key + '.value', 249 prefs.set('prefs.' + testCase.key + '.value',
234 deepCopy(testCase.values[1])); 250 deepCopy(testCase.values[1]));
235 } 251 }
236 // Check that setPref has been called for the right values. 252 // Check that setPref has been called for the right values.
237 expectMockApiPrefsSet(1); 253 assertMockApiPrefsSet(1);
238 254
239 // Test that when setPref fails, the pref is reverted locally. 255 // Test that when setPref fails, the pref is reverted locally.
240 for (var testCase of prefsTestCases) { 256 for (var testCase of prefsTestCases) {
241 mockApi.failNextSetPref(); 257 mockApi.failNextSetPref();
242 prefs.set('prefs.' + testCase.key + '.value', 258 prefs.set('prefs.' + testCase.key + '.value',
243 deepCopy(testCase.values[2])); 259 deepCopy(testCase.values[2]));
244 } 260 }
245 261
246 expectPrefsSet(1); 262 assertPrefsSet(1);
247 263
248 // Test that setPref is not called when the pref doesn't change. 264 // Test that setPref is not called when the pref doesn't change.
249 mockApi.disallowSetPref(); 265 mockApi.disallowSetPref();
250 for (var testCase of prefsTestCases) { 266 for (var testCase of prefsTestCases) {
251 prefs.set('prefs.' + testCase.key + '.value', 267 prefs.set('prefs.' + testCase.key + '.value',
252 deepCopy(testCase.values[1])); 268 deepCopy(testCase.values[1]));
253 } 269 }
254 expectMockApiPrefsSet(1); 270 assertMockApiPrefsSet(1);
255 mockApi.allowSetPref(); 271 mockApi.allowSetPref();
256 }); 272 });
257 273
258 test('responds to API changes', function() { 274 test('responds to API changes', function() {
259 // Changes from the API should not result in those changes being sent 275 // Changes from the API should not result in those changes being sent
260 // back to the API, as this could trigger a race condition. 276 // back to the API, as this could trigger a race condition.
261 mockApi.disallowSetPref(); 277 mockApi.disallowSetPref();
262 var prefChanges = []; 278 var prefChanges = [];
263 for (var testCase of prefsTestCases) 279 for (var testCase of prefsTestCases)
264 prefChanges.push({key: testCase.key, value: testCase.values[1]}); 280 prefChanges.push({key: testCase.key, value: testCase.values[1]});
265 281
266 // Send a set of changes. 282 // Send a set of changes.
267 mockApi.sendPrefChanges(prefChanges); 283 mockApi.sendPrefChanges(prefChanges);
268 expectPrefsSet(1); 284 assertPrefsSet(1);
269 285
270 prefChanges = []; 286 prefChanges = [];
271 for (var testCase of prefsTestCases) 287 for (var testCase of prefsTestCases)
272 prefChanges.push({key: testCase.key, value: testCase.values[2]}); 288 prefChanges.push({key: testCase.key, value: testCase.values[2]});
273 289
274 // Send a second set of changes. 290 // Send a second set of changes.
275 mockApi.sendPrefChanges(prefChanges); 291 mockApi.sendPrefChanges(prefChanges);
276 expectPrefsSet(2); 292 assertPrefsSet(2);
277 293
278 // Send the same set of changes again -- nothing should happen. 294 // Send the same set of changes again -- nothing should happen.
279 mockApi.sendPrefChanges(prefChanges); 295 mockApi.sendPrefChanges(prefChanges);
280 expectPrefsSet(2); 296 assertPrefsSet(2);
281 }); 297 });
282 }); 298 });
283 } 299 }
284 300
285 return { 301 return {
286 registerTests: registerTests, 302 registerTests: registerTests,
287 }; 303 };
288 }); 304 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/settings/prefs/prefs_types.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698