1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/mobilemessage/tests/marionette/test_segment_info.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,188 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + * http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +MARIONETTE_TIMEOUT = 60000; 1.8 + 1.9 +const LEN_7BIT = 160; 1.10 +const LEN_7BIT_WITH_8BIT_REF = 153; 1.11 +const LEN_7BIT_WITH_16BIT_REF = 152; 1.12 +const LEN_UCS2 = 70; 1.13 +const LEN_UCS2_WITH_8BIT_REF = 67; 1.14 +const LEN_UCS2_WITH_16BIT_REF = 66; 1.15 + 1.16 +SpecialPowers.setBoolPref("dom.sms.enabled", true); 1.17 +let currentStrict7BitEncoding = false; 1.18 +SpecialPowers.setBoolPref("dom.sms.strict7BitEncoding", 1.19 + currentStrict7BitEncoding); 1.20 +SpecialPowers.addPermission("sms", true, document); 1.21 + 1.22 +let manager = window.navigator.mozMobileMessage; 1.23 +ok(manager instanceof MozMobileMessageManager, 1.24 + "manager is instance of " + manager.constructor); 1.25 + 1.26 +function times(str, n) { 1.27 + return (new Array(n + 1)).join(str); 1.28 +} 1.29 + 1.30 +let tasks = { 1.31 + // List of test fuctions. Each of them should call |tasks.next()| when 1.32 + // completed or |tasks.finish()| to jump to the last one. 1.33 + _tasks: [], 1.34 + _nextTaskIndex: 0, 1.35 + 1.36 + push: function(func) { 1.37 + this._tasks.push(func); 1.38 + }, 1.39 + 1.40 + next: function() { 1.41 + let index = this._nextTaskIndex++; 1.42 + let task = this._tasks[index]; 1.43 + try { 1.44 + task(); 1.45 + } catch (ex) { 1.46 + ok(false, "test task[" + index + "] throws: " + ex); 1.47 + // Run last task as clean up if possible. 1.48 + if (index != this._tasks.length - 1) { 1.49 + this.finish(); 1.50 + } 1.51 + } 1.52 + }, 1.53 + 1.54 + finish: function() { 1.55 + this._tasks[this._tasks.length - 1](); 1.56 + }, 1.57 + 1.58 + run: function() { 1.59 + this.next(); 1.60 + } 1.61 +}; 1.62 + 1.63 +function addTest(text, strict7BitEncoding, expected) { 1.64 + tasks.push(function() { 1.65 + if (strict7BitEncoding != currentStrict7BitEncoding) { 1.66 + currentStrict7BitEncoding = strict7BitEncoding; 1.67 + SpecialPowers.setBoolPref("dom.sms.strict7BitEncoding", 1.68 + currentStrict7BitEncoding); 1.69 + } 1.70 + 1.71 + let domRequest = manager.getSegmentInfoForText(text); 1.72 + ok(domRequest, "DOMRequest object returned."); 1.73 + 1.74 + domRequest.onsuccess = function(e) { 1.75 + log("Received 'onsuccess' DOMRequest event."); 1.76 + 1.77 + let result = e.target.result; 1.78 + if (!result) { 1.79 + ok(false, "getSegmentInfoForText() result is not valid."); 1.80 + tasks.finish(); 1.81 + return; 1.82 + } 1.83 + 1.84 + is(result.segments, expected[0], "segments"); 1.85 + is(result.charsPerSegment, expected[1], "charsPerSegment"); 1.86 + is(result.charsAvailableInLastSegment, expected[2], 1.87 + "charsAvailableInLastSegment"); 1.88 + 1.89 + tasks.next(); 1.90 + }; 1.91 + 1.92 + domRequest.onerror = function(e) { 1.93 + ok(false, "Failed to call getSegmentInfoForText()."); 1.94 + tasks.finish(); 1.95 + }; 1.96 + }); 1.97 +} 1.98 + 1.99 +// GSM 7Bit Alphabets: 1.100 +// 1.101 +// 'a' is in GSM default locking shift table, so it takes 1 septet. 1.102 +addTest("a", false, [1, LEN_7BIT, LEN_7BIT - 1]); 1.103 +// '\u20ac' is in GSM default single shift table, so it takes 2 septets. 1.104 +addTest("\u20ac", false, [1, LEN_7BIT, LEN_7BIT - 2]); 1.105 +// SP is defined in both locking shift and single shift tables. 1.106 +addTest(" ", false, [1, LEN_7BIT, LEN_7BIT - 1]); 1.107 +// Some combinations. 1.108 +addTest("a\u20ac", false, [1, LEN_7BIT, LEN_7BIT - 3]); 1.109 +addTest("a ", false, [1, LEN_7BIT, LEN_7BIT - 2]); 1.110 +addTest("\u20aca", false, [1, LEN_7BIT, LEN_7BIT - 3]); 1.111 +addTest("\u20ac ", false, [1, LEN_7BIT, LEN_7BIT - 3]); 1.112 +addTest(" \u20ac", false, [1, LEN_7BIT, LEN_7BIT - 3]); 1.113 +addTest(" a", false, [1, LEN_7BIT, LEN_7BIT - 2]); 1.114 + 1.115 +// GSM 7Bit Alphabets (multipart): 1.116 +// 1.117 +// Exactly 160 locking shift table chararacters. 1.118 +addTest(times("a", LEN_7BIT), false, [1, LEN_7BIT, 0]); 1.119 +// 161 locking shift table chararacters. We'll have |161 - 153 = 8| septets in 1.120 +// the 2nd segment. 1.121 +addTest(times("a", LEN_7BIT + 1), false, 1.122 + [2, LEN_7BIT_WITH_8BIT_REF, LEN_7BIT_WITH_8BIT_REF - 8]); 1.123 +// |LEN_7BIT_WITH_8BIT_REF * 2| locking shift table chararacters. 1.124 +addTest(times("a", LEN_7BIT_WITH_8BIT_REF * 2), false, 1.125 + [2, LEN_7BIT_WITH_8BIT_REF, 0]); 1.126 +// |LEN_7BIT_WITH_8BIT_REF * 2 + 1| locking shift table chararacters. 1.127 +addTest(times("a", LEN_7BIT_WITH_8BIT_REF * 2 + 1), false, 1.128 + [3, LEN_7BIT_WITH_8BIT_REF, LEN_7BIT_WITH_8BIT_REF - 1]); 1.129 +// Exactly 80 single shift table chararacters. 1.130 +addTest(times("\u20ac", LEN_7BIT / 2), false, [1, LEN_7BIT, 0]); 1.131 +// 81 single shift table chararacters. Because |Math.floor(153 / 2) = 76|, it 1.132 +// should left 5 septets in the 2nd segment. 1.133 +addTest(times("\u20ac", LEN_7BIT / 2 + 1), false, 1.134 + [2, LEN_7BIT_WITH_8BIT_REF, LEN_7BIT_WITH_8BIT_REF - 10]); 1.135 +// |1 + 2 * 76| single shift table chararacters. We have only |153 - 76 * 2 = 1| 1.136 +// space left, but each single shift table character takes 2, so it will be 1.137 +// filled in the 3rd segment. 1.138 +addTest(times("\u20ac", 1 + 2 * Math.floor(LEN_7BIT_WITH_8BIT_REF / 2)), false, 1.139 + [3, LEN_7BIT_WITH_8BIT_REF, LEN_7BIT_WITH_8BIT_REF - 2]); 1.140 +// |2 * 76| single shift table chararacters + 1 locking shift table chararacter. 1.141 +addTest("a" + times("\u20ac", 2 * Math.floor(LEN_7BIT_WITH_8BIT_REF / 2)), false, 1.142 + [2, LEN_7BIT_WITH_8BIT_REF, 1]); 1.143 +addTest(times("\u20ac", 2 * Math.floor(LEN_7BIT_WITH_8BIT_REF / 2)) + "a", false, 1.144 + [2, LEN_7BIT_WITH_8BIT_REF, 0]); 1.145 + 1.146 +// UCS2: 1.147 +// 1.148 +// '\u6afb' should be encoded as UCS2. 1.149 +addTest("\u6afb", false, [1, LEN_UCS2, LEN_UCS2 - 1]); 1.150 +// Combination of GSM 7bit alphabets. 1.151 +addTest("\u6afba", false, [1, LEN_UCS2, LEN_UCS2 - 2]); 1.152 +addTest("\u6afb\u20ac", false, [1, LEN_UCS2, LEN_UCS2 - 2]); 1.153 +addTest("\u6afb ", false, [1, LEN_UCS2, LEN_UCS2 - 2]); 1.154 + 1.155 +// UCS2 (multipart): 1.156 +// 1.157 +// Exactly 70 UCS2 chararacters. 1.158 +addTest(times("\u6afb", LEN_UCS2), false, [1, LEN_UCS2, 0]); 1.159 +// 71 UCS2 chararacters. We'll have |71 - 67 = 4| chararacters in the 2nd 1.160 +// segment. 1.161 +addTest(times("\u6afb", LEN_UCS2 + 1), false, 1.162 + [2, LEN_UCS2_WITH_8BIT_REF, LEN_UCS2_WITH_8BIT_REF - 4]); 1.163 +// |LEN_UCS2_WITH_8BIT_REF * 2| ucs2 chararacters. 1.164 +addTest(times("\u6afb", LEN_UCS2_WITH_8BIT_REF * 2), false, 1.165 + [2, LEN_UCS2_WITH_8BIT_REF, 0]); 1.166 +// |LEN_7BIT_WITH_8BIT_REF * 2 + 1| ucs2 chararacters. 1.167 +addTest(times("\u6afb", LEN_UCS2_WITH_8BIT_REF * 2 + 1), false, 1.168 + [3, LEN_UCS2_WITH_8BIT_REF, LEN_UCS2_WITH_8BIT_REF - 1]); 1.169 + 1.170 +// Strict 7-Bit Encoding: 1.171 +// 1.172 +// Should have no effect on GSM default alphabet characters. 1.173 +addTest("\u0041", true, [1, LEN_7BIT, LEN_7BIT - 1]); 1.174 +// "\u00c0"(À) should be mapped to "\u0041"(A). 1.175 +addTest("\u00c0", true, [1, LEN_7BIT, LEN_7BIT - 1]); 1.176 +// Mixing mapped characters with unmapped ones. 1.177 +addTest("\u00c0\u0041", true, [1, LEN_7BIT, LEN_7BIT - 2]); 1.178 +addTest("\u0041\u00c0", true, [1, LEN_7BIT, LEN_7BIT - 2]); 1.179 +// UCS2 characters should be mapped to '*'. 1.180 +addTest("\u1234", true, [1, LEN_7BIT, LEN_7BIT - 1]); 1.181 + 1.182 + 1.183 +// WARNING: All tasks should be pushed before this!!! 1.184 +tasks.push(function cleanUp() { 1.185 + SpecialPowers.removePermission("sms", document); 1.186 + SpecialPowers.clearUserPref("dom.sms.enabled"); 1.187 + SpecialPowers.clearUserPref("dom.sms.strict7BitEncoding"); 1.188 + finish(); 1.189 +}); 1.190 + 1.191 +tasks.run();