assert.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  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 file,
  3. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
  6. Cu.import("resource://gre/modules/AppConstants.jsm");
  7. Cu.import("resource://gre/modules/Preferences.jsm");
  8. Cu.import("resource://gre/modules/Services.jsm");
  9. Cu.import("chrome://marionette/content/error.js");
  10. this.EXPORTED_SYMBOLS = ["assert"];
  11. const isFennec = () => AppConstants.platform == "android";
  12. const isB2G = () => false;
  13. const isFirefox = () => Services.appinfo.name == "Firefox";
  14. /** Shorthands for common assertions made in Marionette. */
  15. this.assert = {};
  16. /**
  17. * Asserts that Marionette has a session.
  18. *
  19. * @param {GeckoDriver} driver
  20. * Marionette driver instance.
  21. * @param {string=} msg
  22. * Custom error message.
  23. *
  24. * @return {string}
  25. * Session ID.
  26. *
  27. * @throws {InvalidSessionIDError}
  28. * If |driver| does not have a session ID.
  29. */
  30. assert.session = function (driver, msg = "") {
  31. assert.that(sessionID => sessionID,
  32. msg, InvalidSessionIDError)(driver.sessionId);
  33. return driver.sessionId;
  34. };
  35. /**
  36. * Asserts that the current browser is Firefox Desktop.
  37. *
  38. * @param {string=} msg
  39. * Custom error message.
  40. *
  41. * @throws {UnsupportedOperationError}
  42. * If current browser is not Firefox.
  43. */
  44. assert.firefox = function (msg = "") {
  45. msg = msg || "Only supported in Firefox";
  46. assert.that(isFirefox, msg, UnsupportedOperationError)();
  47. };
  48. /**
  49. * Asserts that the current browser is Fennec, or Firefox for Android.
  50. *
  51. * @param {string=} msg
  52. * Custom error message.
  53. *
  54. * @throws {UnsupportedOperationError}
  55. * If current browser is not Fennec.
  56. */
  57. assert.fennec = function (msg = "") {
  58. msg = msg || "Only supported in Fennec";
  59. assert.that(isFennec, msg, UnsupportedOperationError)();
  60. };
  61. /**
  62. * Asserts that the current browser is B2G.
  63. *
  64. * @param {string=} msg
  65. * Custom error message.
  66. *
  67. * @throws {UnsupportedOperationError}
  68. * If the current browser is not B2G.
  69. */
  70. assert.b2g = function (msg = "") {
  71. msg = msg || "Only supported in B2G";
  72. assert.that(isB2G, msg, UnsupportedOperationError)();
  73. };
  74. /**
  75. * Asserts that the current |context| is content.
  76. *
  77. * @param {string} context
  78. * Context to test.
  79. * @param {string=} msg
  80. * Custom error message.
  81. *
  82. * @return {string}
  83. * |context| is returned unaltered.
  84. *
  85. * @throws {UnsupportedOperationError}
  86. * If |context| is not content.
  87. */
  88. assert.content = function (context, msg = "") {
  89. msg = msg || "Only supported in content context";
  90. assert.that(c => c.toString() == "content", msg, UnsupportedOperationError)(context);
  91. };
  92. /**
  93. * Asserts that the current browser is a mobile browser, that is either
  94. * B2G or Fennec.
  95. *
  96. * @param {string=} msg
  97. * Custom error message.
  98. *
  99. * @throws {UnsupportedOperationError}
  100. * If the current browser is not B2G or Fennec.
  101. */
  102. assert.mobile = function (msg = "") {
  103. msg = msg || "Only supported in Fennec or B2G";
  104. assert.that(() => isFennec() || isB2G(), msg, UnsupportedOperationError)();
  105. };
  106. /**
  107. * Asserts that |obj| is defined.
  108. *
  109. * @param {?} obj
  110. * Value to test.
  111. * @param {string=} msg
  112. * Custom error message.
  113. *
  114. * @return {?}
  115. * |obj| is returned unaltered.
  116. *
  117. * @throws {InvalidArgumentError}
  118. * If |obj| is not defined.
  119. */
  120. assert.defined = function (obj, msg = "") {
  121. msg = msg || error.pprint`Expected ${obj} to be defined`;
  122. return assert.that(o => typeof o != "undefined", msg)(obj);
  123. };
  124. /**
  125. * Asserts that |obj| is a finite number.
  126. *
  127. * @param {?} obj
  128. * Value to test.
  129. * @param {string=} msg
  130. * Custom error message.
  131. *
  132. * @return {number}
  133. * |obj| is returned unaltered.
  134. *
  135. * @throws {InvalidArgumentError}
  136. * If |obj| is not a number.
  137. */
  138. assert.number = function (obj, msg = "") {
  139. msg = msg || error.pprint`Expected ${obj} to be finite number`;
  140. return assert.that(Number.isFinite, msg)(obj);
  141. };
  142. /**
  143. * Asserts that |obj| is an integer.
  144. *
  145. * @param {?} obj
  146. * Value to test.
  147. * @param {string=} msg
  148. * Custom error message.
  149. *
  150. * @return {number}
  151. * |obj| is returned unaltered.
  152. *
  153. * @throws {InvalidArgumentError}
  154. * If |obj| is not an integer.
  155. */
  156. assert.integer = function (obj, msg = "") {
  157. msg = msg || error.pprint`Expected ${obj} to be an integer`;
  158. return assert.that(Number.isInteger, msg)(obj);
  159. };
  160. /**
  161. * Asserts that |obj| is a positive integer.
  162. *
  163. * @param {?} obj
  164. * Value to test.
  165. * @param {string=} msg
  166. * Custom error message.
  167. *
  168. * @return {number}
  169. * |obj| is returned unaltered.
  170. *
  171. * @throws {InvalidArgumentError}
  172. * If |obj| is not a positive integer.
  173. */
  174. assert.positiveInteger = function (obj, msg = "") {
  175. assert.integer(obj, msg);
  176. msg = msg || error.pprint`Expected ${obj} to be >= 0`;
  177. return assert.that(n => n >= 0, msg)(obj);
  178. };
  179. /**
  180. * Asserts that |obj| is a boolean.
  181. *
  182. * @param {?} obj
  183. * Value to test.
  184. * @param {string=} msg
  185. * Custom error message.
  186. *
  187. * @return {boolean}
  188. * |obj| is returned unaltered.
  189. *
  190. * @throws {InvalidArgumentError}
  191. * If |obj| is not a boolean.
  192. */
  193. assert.boolean = function (obj, msg = "") {
  194. msg = msg || error.pprint`Expected ${obj} to be boolean`;
  195. return assert.that(b => typeof b == "boolean", msg)(obj);
  196. };
  197. /**
  198. * Asserts that |obj| is a string.
  199. *
  200. * @param {?} obj
  201. * Value to test.
  202. * @param {string=} msg
  203. * Custom error message.
  204. *
  205. * @return {string}
  206. * |obj| is returned unaltered.
  207. *
  208. * @throws {InvalidArgumentError}
  209. * If |obj| is not a string.
  210. */
  211. assert.string = function (obj, msg = "") {
  212. msg = msg || error.pprint`Expected ${obj} to be a string`;
  213. return assert.that(s => typeof s == "string", msg)(obj);
  214. };
  215. /**
  216. * Asserts that |obj| is an object.
  217. *
  218. * @param {?} obj
  219. * Value to test.
  220. * @param {string=} msg
  221. * Custom error message.
  222. *
  223. * @return {Object}
  224. * |obj| is returned unaltered.
  225. *
  226. * @throws {InvalidArgumentError}
  227. * If |obj| is not an object.
  228. */
  229. assert.object = function (obj, msg = "") {
  230. msg = msg || error.pprint`Expected ${obj} to be an object`;
  231. return assert.that(o =>
  232. Object.prototype.toString.call(o) == "[object Object]", msg)(obj);
  233. };
  234. /**
  235. * Asserts that |prop| is in |obj|.
  236. *
  237. * @param {?} prop
  238. * Own property to test if is in |obj|.
  239. * @param {?} obj
  240. * Object.
  241. * @param {string=} msg
  242. * Custom error message.
  243. *
  244. * @return {?}
  245. * Value of |obj|'s own property |prop|.
  246. *
  247. * @throws {InvalidArgumentError}
  248. * If |prop| is not in |obj|, or |obj| is not an object.
  249. */
  250. assert.in = function (prop, obj, msg = "") {
  251. assert.object(obj, msg);
  252. msg = msg || error.pprint`Expected ${prop} in ${obj}`;
  253. assert.that(p => obj.hasOwnProperty(p), msg)(prop);
  254. return obj[prop];
  255. };
  256. /**
  257. * Asserts that |obj| is an Array.
  258. *
  259. * @param {?} obj
  260. * Value to test.
  261. * @param {string=} msg
  262. * Custom error message.
  263. *
  264. * @return {Object}
  265. * |obj| is returned unaltered.
  266. *
  267. * @throws {InvalidArgumentError}
  268. * If |obj| is not an Array.
  269. */
  270. assert.array = function (obj, msg = "") {
  271. msg = msg || error.pprint`Expected ${obj} to be an Array`;
  272. return assert.that(Array.isArray, msg)(obj);
  273. };
  274. /**
  275. * Returns a function that is used to assert the |predicate|.
  276. *
  277. * @param {function(?): boolean} predicate
  278. * Evaluated on calling the return value of this function. If its
  279. * return value of the inner function is false, |error| is thrown
  280. * with |message|.
  281. * @param {string=} message
  282. * Custom error message.
  283. * @param {Error=} error
  284. * Custom error type by its class.
  285. *
  286. * @return {function(?): ?}
  287. * Function that takes and returns the passed in value unaltered, and
  288. * which may throw |error| with |message| if |predicate| evaluates
  289. * to false.
  290. */
  291. assert.that = function (
  292. predicate, message = "", error = InvalidArgumentError) {
  293. return obj => {
  294. if (!predicate(obj)) {
  295. throw new error(message);
  296. }
  297. return obj;
  298. };
  299. };