1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/test/test-api-utils.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,316 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +const apiUtils = require("sdk/deprecated/api-utils"); 1.9 + 1.10 +exports.testValidateOptionsEmpty = function (assert) { 1.11 + let val = apiUtils.validateOptions(null, {}); 1.12 + 1.13 + assert.deepEqual(val, {}); 1.14 + 1.15 + val = apiUtils.validateOptions(null, { foo: {} }); 1.16 + assert.deepEqual(val, {}); 1.17 + 1.18 + val = apiUtils.validateOptions({}, {}); 1.19 + assert.deepEqual(val, {}); 1.20 + 1.21 + val = apiUtils.validateOptions({}, { foo: {} }); 1.22 + assert.deepEqual(val, {}); 1.23 +}; 1.24 + 1.25 +exports.testValidateOptionsNonempty = function (assert) { 1.26 + let val = apiUtils.validateOptions({ foo: 123 }, {}); 1.27 + assert.deepEqual(val, {}); 1.28 + 1.29 + val = apiUtils.validateOptions({ foo: 123, bar: 456 }, 1.30 + { foo: {}, bar: {}, baz: {} }); 1.31 + 1.32 + assert.deepEqual(val, { foo: 123, bar: 456 }); 1.33 +}; 1.34 + 1.35 +exports.testValidateOptionsMap = function (assert) { 1.36 + let val = apiUtils.validateOptions({ foo: 3, bar: 2 }, { 1.37 + foo: { map: function (v) v * v }, 1.38 + bar: { map: function (v) undefined } 1.39 + }); 1.40 + assert.deepEqual(val, { foo: 9, bar: undefined }); 1.41 +}; 1.42 + 1.43 +exports.testValidateOptionsMapException = function (assert) { 1.44 + let val = apiUtils.validateOptions({ foo: 3 }, { 1.45 + foo: { map: function () { throw new Error(); }} 1.46 + }); 1.47 + assert.deepEqual(val, { foo: 3 }); 1.48 +}; 1.49 + 1.50 +exports.testValidateOptionsOk = function (assert) { 1.51 + let val = apiUtils.validateOptions({ foo: 3, bar: 2, baz: 1 }, { 1.52 + foo: { ok: function (v) v }, 1.53 + bar: { ok: function (v) v } 1.54 + }); 1.55 + assert.deepEqual(val, { foo: 3, bar: 2 }); 1.56 + 1.57 + assert.throws( 1.58 + function () apiUtils.validateOptions({ foo: 2, bar: 2 }, { 1.59 + bar: { ok: function (v) v > 2 } 1.60 + }), 1.61 + /^The option "bar" is invalid/, 1.62 + "ok should raise exception on invalid option" 1.63 + ); 1.64 + 1.65 + assert.throws( 1.66 + function () apiUtils.validateOptions(null, { foo: { ok: function (v) v }}), 1.67 + /^The option "foo" is invalid/, 1.68 + "ok should raise exception on invalid option" 1.69 + ); 1.70 +}; 1.71 + 1.72 +exports.testValidateOptionsIs = function (assert) { 1.73 + let opts = { 1.74 + array: [], 1.75 + boolean: true, 1.76 + func: function () {}, 1.77 + nul: null, 1.78 + number: 1337, 1.79 + object: {}, 1.80 + string: "foo", 1.81 + undef1: undefined 1.82 + }; 1.83 + let requirements = { 1.84 + array: { is: ["array"] }, 1.85 + boolean: { is: ["boolean"] }, 1.86 + func: { is: ["function"] }, 1.87 + nul: { is: ["null"] }, 1.88 + number: { is: ["number"] }, 1.89 + object: { is: ["object"] }, 1.90 + string: { is: ["string"] }, 1.91 + undef1: { is: ["undefined"] }, 1.92 + undef2: { is: ["undefined"] } 1.93 + }; 1.94 + let val = apiUtils.validateOptions(opts, requirements); 1.95 + assert.deepEqual(val, opts); 1.96 + 1.97 + assert.throws( 1.98 + function () apiUtils.validateOptions(null, { 1.99 + foo: { is: ["object", "number"] } 1.100 + }), 1.101 + /^The option "foo" must be one of the following types: object, number/, 1.102 + "Invalid type should raise exception" 1.103 + ); 1.104 +}; 1.105 + 1.106 +exports.testValidateOptionsIsWithExportedValue = function (assert) { 1.107 + let { string, number, boolean, object } = apiUtils; 1.108 + 1.109 + let opts = { 1.110 + boolean: true, 1.111 + number: 1337, 1.112 + object: {}, 1.113 + string: "foo" 1.114 + }; 1.115 + let requirements = { 1.116 + string: { is: string }, 1.117 + number: { is: number }, 1.118 + boolean: { is: boolean }, 1.119 + object: { is: object } 1.120 + }; 1.121 + let val = apiUtils.validateOptions(opts, requirements); 1.122 + assert.deepEqual(val, opts); 1.123 + 1.124 + // Test the types are optional by default 1.125 + val = apiUtils.validateOptions({foo: 'bar'}, requirements); 1.126 + assert.deepEqual(val, {}); 1.127 +}; 1.128 + 1.129 +exports.testValidateOptionsIsWithEither = function (assert) { 1.130 + let { string, number, boolean, either } = apiUtils; 1.131 + let text = { is: either(string, number) }; 1.132 + 1.133 + let requirements = { 1.134 + text: text, 1.135 + boolOrText: { is: either(text, boolean) } 1.136 + }; 1.137 + 1.138 + let val = apiUtils.validateOptions({text: 12}, requirements); 1.139 + assert.deepEqual(val, {text: 12}); 1.140 + 1.141 + val = apiUtils.validateOptions({text: "12"}, requirements); 1.142 + assert.deepEqual(val, {text: "12"}); 1.143 + 1.144 + val = apiUtils.validateOptions({boolOrText: true}, requirements); 1.145 + assert.deepEqual(val, {boolOrText: true}); 1.146 + 1.147 + val = apiUtils.validateOptions({boolOrText: "true"}, requirements); 1.148 + assert.deepEqual(val, {boolOrText: "true"}); 1.149 + 1.150 + val = apiUtils.validateOptions({boolOrText: 1}, requirements); 1.151 + assert.deepEqual(val, {boolOrText: 1}); 1.152 + 1.153 + assert.throws( 1.154 + () => apiUtils.validateOptions({text: true}, requirements), 1.155 + /^The option "text" must be one of the following types/, 1.156 + "Invalid type should raise exception" 1.157 + ); 1.158 + 1.159 + assert.throws( 1.160 + () => apiUtils.validateOptions({boolOrText: []}, requirements), 1.161 + /^The option "boolOrText" must be one of the following types/, 1.162 + "Invalid type should raise exception" 1.163 + ); 1.164 +}; 1.165 + 1.166 +exports.testValidateOptionsWithRequiredAndOptional = function (assert) { 1.167 + let { string, number, required, optional } = apiUtils; 1.168 + 1.169 + let opts = { 1.170 + number: 1337, 1.171 + string: "foo" 1.172 + }; 1.173 + 1.174 + let requirements = { 1.175 + string: required(string), 1.176 + number: number 1.177 + }; 1.178 + 1.179 + let val = apiUtils.validateOptions(opts, requirements); 1.180 + assert.deepEqual(val, opts); 1.181 + 1.182 + val = apiUtils.validateOptions({string: "foo"}, requirements); 1.183 + assert.deepEqual(val, {string: "foo"}); 1.184 + 1.185 + assert.throws( 1.186 + () => apiUtils.validateOptions({number: 10}, requirements), 1.187 + /^The option "string" must be one of the following types/, 1.188 + "Invalid type should raise exception" 1.189 + ); 1.190 + 1.191 + // Makes string optional 1.192 + requirements.string = optional(requirements.string); 1.193 + 1.194 + val = apiUtils.validateOptions({number: 10}, requirements), 1.195 + assert.deepEqual(val, {number: 10}); 1.196 + 1.197 +}; 1.198 + 1.199 + 1.200 + 1.201 +exports.testValidateOptionsWithExportedValue = function (assert) { 1.202 + let { string, number, boolean, object } = apiUtils; 1.203 + 1.204 + let opts = { 1.205 + boolean: true, 1.206 + number: 1337, 1.207 + object: {}, 1.208 + string: "foo" 1.209 + }; 1.210 + let requirements = { 1.211 + string: string, 1.212 + number: number, 1.213 + boolean: boolean, 1.214 + object: object 1.215 + }; 1.216 + let val = apiUtils.validateOptions(opts, requirements); 1.217 + assert.deepEqual(val, opts); 1.218 + 1.219 + // Test the types are optional by default 1.220 + val = apiUtils.validateOptions({foo: 'bar'}, requirements); 1.221 + assert.deepEqual(val, {}); 1.222 +}; 1.223 + 1.224 + 1.225 +exports.testValidateOptionsMapIsOk = function (assert) { 1.226 + let [map, is, ok] = [false, false, false]; 1.227 + let val = apiUtils.validateOptions({ foo: 1337 }, { 1.228 + foo: { 1.229 + map: function (v) v.toString(), 1.230 + is: ["string"], 1.231 + ok: function (v) v.length > 0 1.232 + } 1.233 + }); 1.234 + assert.deepEqual(val, { foo: "1337" }); 1.235 + 1.236 + let requirements = { 1.237 + foo: { 1.238 + is: ["object"], 1.239 + ok: function () assert.fail("is should have caused us to throw by now") 1.240 + } 1.241 + }; 1.242 + assert.throws( 1.243 + function () apiUtils.validateOptions(null, requirements), 1.244 + /^The option "foo" must be one of the following types: object/, 1.245 + "is should be used before ok is called" 1.246 + ); 1.247 +}; 1.248 + 1.249 +exports.testValidateOptionsErrorMsg = function (assert) { 1.250 + assert.throws( 1.251 + function () apiUtils.validateOptions(null, { 1.252 + foo: { ok: function (v) v, msg: "foo!" } 1.253 + }), 1.254 + /^foo!/, 1.255 + "ok should raise exception with customized message" 1.256 + ); 1.257 +}; 1.258 + 1.259 +exports.testValidateMapWithMissingKey = function (assert) { 1.260 + let val = apiUtils.validateOptions({ }, { 1.261 + foo: { 1.262 + map: function (v) v || "bar" 1.263 + } 1.264 + }); 1.265 + assert.deepEqual(val, { foo: "bar" }); 1.266 + 1.267 + val = apiUtils.validateOptions({ }, { 1.268 + foo: { 1.269 + map: function (v) { throw "bar" } 1.270 + } 1.271 + }); 1.272 + assert.deepEqual(val, { }); 1.273 +}; 1.274 + 1.275 +exports.testValidateMapWithMissingKeyAndThrown = function (assert) { 1.276 + let val = apiUtils.validateOptions({}, { 1.277 + bar: { 1.278 + map: function(v) { throw "bar" } 1.279 + }, 1.280 + baz: { 1.281 + map: function(v) "foo" 1.282 + } 1.283 + }); 1.284 + assert.deepEqual(val, { baz: "foo" }); 1.285 +}; 1.286 + 1.287 +exports.testAddIterator = function testAddIterator (assert) { 1.288 + let obj = {}; 1.289 + let keys = ["foo", "bar", "baz"]; 1.290 + let vals = [1, 2, 3]; 1.291 + let keysVals = [["foo", 1], ["bar", 2], ["baz", 3]]; 1.292 + apiUtils.addIterator( 1.293 + obj, 1.294 + function keysValsGen() { 1.295 + for each (let keyVal in keysVals) 1.296 + yield keyVal; 1.297 + } 1.298 + ); 1.299 + 1.300 + let keysItr = []; 1.301 + for (let key in obj) 1.302 + keysItr.push(key); 1.303 + 1.304 + assert.equal(keysItr.length, keys.length, 1.305 + "the keys iterator returns the correct number of items"); 1.306 + for (let i = 0; i < keys.length; i++) 1.307 + assert.equal(keysItr[i], keys[i], "the key is correct"); 1.308 + 1.309 + let valsItr = []; 1.310 + for each (let val in obj) 1.311 + valsItr.push(val); 1.312 + assert.equal(valsItr.length, vals.length, 1.313 + "the vals iterator returns the correct number of items"); 1.314 + for (let i = 0; i < vals.length; i++) 1.315 + assert.equal(valsItr[i], vals[i], "the val is correct"); 1.316 + 1.317 +}; 1.318 + 1.319 +require('test').run(exports);