Name: js-handler/node_modules/restify/node_modules/node-uuid/test/test.js
| 1: | if (!this.uuid) { |
| 2: | // node.js |
| 3: | uuid = require('../uuid'); |
| 4: | } |
| 5: | |
| 6: | // |
| 7: | // x-platform log/assert shims |
| 8: | // |
| 9: | |
| 10: | function _log(msg, type) { |
| 11: | type = type || 'log'; |
| 12: | |
| 13: | if (typeof(document) != 'undefined') { |
| 14: | document.write('<div class="' + type + '">' + msg.replace(/\n/g, '<br />') + '</div>'); |
| 15: | } |
| 16: | if (typeof(console) != 'undefined') { |
| 17: | var color = { |
| 18: | log: '\033[39m', |
| 19: | warn: '\033[33m', |
| 20: | error: '\033[31m' |
| 21: | }; |
| 22: | console[type](color[type] + msg + color.log); |
| 23: | } |
| 24: | } |
| 25: | |
| 26: | function log(msg) {_log(msg, 'log');} |
| 27: | function warn(msg) {_log(msg, 'warn');} |
| 28: | function error(msg) {_log(msg, 'error');} |
| 29: | |
| 30: | function assert(res, msg) { |
| 31: | if (!res) { |
| 32: | error('FAIL: ' + msg); |
| 33: | } else { |
| 34: | log('Pass: ' + msg); |
| 35: | } |
| 36: | } |
| 37: | |
| 38: | // |
| 39: | // Unit tests |
| 40: | // |
| 41: | |
| 42: | // Verify ordering of v1 ids created with explicit times |
| 43: | var TIME = 1321644961388; // 2011-11-18 11:36:01.388-08:00 |
| 44: | |
| 45: | function compare(name, ids) { |
| 46: | ids = ids.map(function(id) { |
| 47: | return id.split('-').reverse().join('-'); |
| 48: | }).sort(); |
| 49: | var sorted = ([].concat(ids)).sort(); |
| 50: | |
| 51: | assert(sorted.toString() == ids.toString(), name + ' have expected order'); |
| 52: | } |
| 53: | |
| 54: | // Verify ordering of v1 ids created using default behavior |
| 55: | compare('uuids with current time', [ |
| 56: | uuid.v1(), |
| 57: | uuid.v1(), |
| 58: | uuid.v1(), |
| 59: | uuid.v1(), |
| 60: | uuid.v1() |
| 61: | ]); |
| 62: | |
| 63: | // Verify ordering of v1 ids created with explicit times |
| 64: | compare('uuids with time option', [ |
| 65: | uuid.v1({msecs: TIME - 10*3600*1000}), |
| 66: | uuid.v1({msecs: TIME - 1}), |
| 67: | uuid.v1({msecs: TIME}), |
| 68: | uuid.v1({msecs: TIME + 1}), |
| 69: | uuid.v1({msecs: TIME + 28*24*3600*1000}) |
| 70: | ]); |
| 71: | |
| 72: | assert( |
| 73: | uuid.v1({msecs: TIME}) != uuid.v1({msecs: TIME}), |
| 74: | 'IDs created at same msec are different' |
| 75: | ); |
| 76: | |
| 77: | // Verify throw if too many ids created |
| 78: | var thrown = false; |
| 79: | try { |
| 80: | uuid.v1({msecs: TIME, nsecs: 10000}); |
| 81: | } catch (e) { |
| 82: | thrown = true; |
| 83: | } |
| 84: | assert(thrown, 'Exception thrown when > 10K ids created in 1 ms'); |
| 85: | |
| 86: | // Verify clock regression bumps clockseq |
| 87: | var uidt = uuid.v1({msecs: TIME}); |
| 88: | var uidtb = uuid.v1({msecs: TIME - 1}); |
| 89: | assert( |
| 90: | parseInt(uidtb.split('-')[3], 16) - parseInt(uidt.split('-')[3], 16) === 1, |
| 91: | 'Clock regression by msec increments the clockseq' |
| 92: | ); |
| 93: | |
| 94: | // Verify clock regression bumps clockseq |
| 95: | var uidtn = uuid.v1({msecs: TIME, nsecs: 10}); |
| 96: | var uidtnb = uuid.v1({msecs: TIME, nsecs: 9}); |
| 97: | assert( |
| 98: | parseInt(uidtnb.split('-')[3], 16) - parseInt(uidtn.split('-')[3], 16) === 1, |
| 99: | 'Clock regression by nsec increments the clockseq' |
| 100: | ); |
| 101: | |
| 102: | // Verify explicit options produce expected id |
| 103: | var id = uuid.v1({ |
| 104: | msecs: 1321651533573, |
| 105: | nsecs: 5432, |
| 106: | clockseq: 0x385c, |
| 107: | node: [ 0x61, 0xcd, 0x3c, 0xbb, 0x32, 0x10 ] |
| 108: | }); |
| 109: | assert(id == 'd9428888-122b-11e1-b85c-61cd3cbb3210', 'Explicit options produce expected id'); |
| 110: | |
| 111: | // Verify adjacent ids across a msec boundary are 1 time unit apart |
| 112: | var u0 = uuid.v1({msecs: TIME, nsecs: 9999}); |
| 113: | var u1 = uuid.v1({msecs: TIME + 1, nsecs: 0}); |
| 114: | |
| 115: | var before = u0.split('-')[0], after = u1.split('-')[0]; |
| 116: | var dt = parseInt(after, 16) - parseInt(before, 16); |
| 117: | assert(dt === 1, 'Ids spanning 1ms boundary are 100ns apart'); |
| 118: | |
| 119: | // |
| 120: | // Test parse/unparse |
| 121: | // |
| 122: | |
| 123: | id = '00112233445566778899aabbccddeeff'; |
| 124: | assert(uuid.unparse(uuid.parse(id.substr(0,10))) == |
| 125: | '00112233-4400-0000-0000-000000000000', 'Short parse'); |
| 126: | assert(uuid.unparse(uuid.parse('(this is the uuid -> ' + id + id)) == |
| 127: | '00112233-4455-6677-8899-aabbccddeeff', 'Dirty parse'); |
| 128: | |
| 129: | // |
| 130: | // Perf tests |
| 131: | // |
| 132: | |
| 133: | var generators = { |
| 134: | v1: uuid.v1, |
| 135: | v4: uuid.v4 |
| 136: | }; |
| 137: | |
| 138: | var UUID_FORMAT = { |
| 139: | v1: /[0-9a-f]{8}-[0-9a-f]{4}-1[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i, |
| 140: | v4: /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i |
| 141: | }; |
| 142: | |
| 143: | var N = 1e4; |
| 144: | |
| 145: | // Get %'age an actual value differs from the ideal value |
| 146: | function divergence(actual, ideal) { |
| 147: | return Math.round(100*100*(actual - ideal)/ideal)/100; |
| 148: | } |
| 149: | |
| 150: | function rate(msg, t) { |
| 151: | log(msg + ': ' + (N / (Date.now() - t) * 1e3 | 0) + ' uuids\/second'); |
| 152: | } |
| 153: | |
| 154: | for (var version in generators) { |
| 155: | var counts = {}, max = 0; |
| 156: | var generator = generators[version]; |
| 157: | var format = UUID_FORMAT[version]; |
| 158: | |
| 159: | log('\nSanity check ' + N + ' ' + version + ' uuids'); |
| 160: | for (var i = 0, ok = 0; i < N; i++) { |
| 161: | id = generator(); |
| 162: | if (!format.test(id)) { |
| 163: | throw Error(id + ' is not a valid UUID string'); |
| 164: | } |
| 165: | |
| 166: | if (id != uuid.unparse(uuid.parse(id))) { |
| 167: | assert(fail, id + ' is not a valid id'); |
| 168: | } |
| 169: | |
| 170: | // Count digits for our randomness check |
| 171: | if (version == 'v4') { |
| 172: | var digits = id.replace(/-/g, '').split(''); |
| 173: | for (var j = digits.length-1; j >= 0; j--) { |
| 174: | var c = digits[j]; |
| 175: | max = Math.max(max, counts[c] = (counts[c] || 0) + 1); |
| 176: | } |
| 177: | } |
| 178: | } |
| 179: | |
| 180: | // Check randomness for v4 UUIDs |
| 181: | if (version == 'v4') { |
| 182: | // Limit that we get worried about randomness. (Purely empirical choice, this!) |
| 183: | var limit = 2*100*Math.sqrt(1/N); |
| 184: | |
| 185: | log('\nChecking v4 randomness. Distribution of Hex Digits (% deviation from ideal)'); |
| 186: | |
| 187: | for (var i = 0; i < 16; i++) { |
| 188: | var c = i.toString(16); |
| 189: | var bar = '', n = counts[c], p = Math.round(n/max*100|0); |
| 190: | |
| 191: | // 1-3,5-8, and D-F: 1:16 odds over 30 digits |
| 192: | var ideal = N*30/16; |
| 193: | if (i == 4) { |
| 194: | // 4: 1:1 odds on 1 digit, plus 1:16 odds on 30 digits |
| 195: | ideal = N*(1 + 30/16); |
| 196: | } else if (i >= 8 && i <= 11) { |
| 197: | // 8-B: 1:4 odds on 1 digit, plus 1:16 odds on 30 digits |
| 198: | ideal = N*(1/4 + 30/16); |
| 199: | } else { |
| 200: | // Otherwise: 1:16 odds on 30 digits |
| 201: | ideal = N*30/16; |
| 202: | } |
| 203: | var d = divergence(n, ideal); |
| 204: | |
| 205: | // Draw bar using UTF squares (just for grins) |
| 206: | var s = n/max*50 | 0; |
| 207: | while (s--) bar += '='; |
| 208: | |
| 209: | assert(Math.abs(d) < limit, c + ' |' + bar + '| ' + counts[c] + ' (' + d + '% < ' + limit + '%)'); |
| 210: | } |
| 211: | } |
| 212: | } |
| 213: | |
| 214: | // Perf tests |
| 215: | for (var version in generators) { |
| 216: | log('\nPerformance testing ' + version + ' UUIDs'); |
| 217: | var generator = generators[version]; |
| 218: | var buf = new uuid.BufferClass(16); |
| 219: | |
| 220: | for (var i = 0, t = Date.now(); i < N; i++) generator(); |
| 221: | rate('uuid.' + version + '()', t); |
| 222: | |
| 223: | for (var i = 0, t = Date.now(); i < N; i++) generator('binary'); |
| 224: | rate('uuid.' + version + '(\'binary\')', t); |
| 225: | |
| 226: | for (var i = 0, t = Date.now(); i < N; i++) generator('binary', buf); |
| 227: | rate('uuid.' + version + '(\'binary\', buffer)', t); |
| 228: | } |
