1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5/* This is a JavaScript module (JSM) to be imported via
6   Components.utils.import() and acts as a singleton.
7   Only the following listed symbols will exposed on import, and only when
8   and where imported. */
9
10var EXPORTED_SYMBOLS = ["Preference"];
11
12const WEAVE_PREF_PREFIX = "services.sync.prefs.sync.";
13
14const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
15const { Logger } = ChromeUtils.import("resource://tps/logger.jsm");
16
17/**
18 * Preference class constructor
19 *
20 * Initializes instance properties.
21 */
22function Preference(props) {
23  Logger.AssertTrue(
24    "name" in props && "value" in props,
25    "Preference must have both name and value"
26  );
27
28  this.name = props.name;
29  this.value = props.value;
30}
31
32/**
33 * Preference instance methods
34 */
35Preference.prototype = {
36  /**
37   * Modify
38   *
39   * Sets the value of the preference this.name to this.value.
40   * Throws on error.
41   *
42   * @return nothing
43   */
44  Modify() {
45    // Determine if this pref is actually something Weave even looks at.
46    let weavepref = WEAVE_PREF_PREFIX + this.name;
47    try {
48      let syncPref = Services.prefs.getBoolPref(weavepref);
49      if (!syncPref) {
50        Services.prefs.setBoolPref(weavepref, true);
51      }
52    } catch (e) {
53      Logger.AssertTrue(false, "Weave doesn't sync pref " + this.name);
54    }
55
56    // Modify the pref; throw an exception if the pref type is different
57    // than the value type specified in the test.
58    let prefType = Services.prefs.getPrefType(this.name);
59    switch (prefType) {
60      case Ci.nsIPrefBranch.PREF_INT:
61        Logger.AssertEqual(
62          typeof this.value,
63          "number",
64          "Wrong type used for preference value"
65        );
66        Services.prefs.setIntPref(this.name, this.value);
67        break;
68      case Ci.nsIPrefBranch.PREF_STRING:
69        Logger.AssertEqual(
70          typeof this.value,
71          "string",
72          "Wrong type used for preference value"
73        );
74        Services.prefs.setCharPref(this.name, this.value);
75        break;
76      case Ci.nsIPrefBranch.PREF_BOOL:
77        Logger.AssertEqual(
78          typeof this.value,
79          "boolean",
80          "Wrong type used for preference value"
81        );
82        Services.prefs.setBoolPref(this.name, this.value);
83        break;
84    }
85  },
86
87  /**
88   * Find
89   *
90   * Verifies that the preference this.name has the value
91   * this.value. Throws on error, or if the pref's type or value
92   * doesn't match.
93   *
94   * @return nothing
95   */
96  Find() {
97    // Read the pref value.
98    let value;
99    try {
100      let prefType = Services.prefs.getPrefType(this.name);
101      switch (prefType) {
102        case Ci.nsIPrefBranch.PREF_INT:
103          value = Services.prefs.getIntPref(this.name);
104          break;
105        case Ci.nsIPrefBranch.PREF_STRING:
106          value = Services.prefs.getCharPref(this.name);
107          break;
108        case Ci.nsIPrefBranch.PREF_BOOL:
109          value = Services.prefs.getBoolPref(this.name);
110          break;
111      }
112    } catch (e) {
113      Logger.AssertTrue(false, "Error accessing pref " + this.name);
114    }
115
116    // Throw an exception if the current and expected values aren't of
117    // the same type, or don't have the same values.
118    Logger.AssertEqual(
119      typeof value,
120      typeof this.value,
121      "Value types don't match"
122    );
123    Logger.AssertEqual(value, this.value, "Preference values don't match");
124  },
125};
126