1 | 'use strict';
|
2 |
|
3 | var assert = require('assert');
|
4 | var crypto = require('crypto');
|
5 | var hash = require('../index');
|
6 | var validSha1 = /^[0-9a-f]{40}$/i;
|
7 |
|
8 | describe('hash()ing different types', function() {
|
9 | it('hashes non-object types', function() {
|
10 | var func = function(a){ return a + 1; };
|
11 | var asyncFunc;
|
12 | try {
|
13 | asyncFunc = eval('async function(a) { return a + 1; }');
|
14 | } catch (err) {
|
15 | if (err.name === 'SyntaxError') asyncFunc = func;
|
16 | else throw err;
|
17 | }
|
18 | assert.ok(validSha1.test(hash('Shazbot!')), 'hash string');
|
19 | assert.ok(validSha1.test(hash(42)), 'hash number');
|
20 | assert.ok(validSha1.test(hash(NaN)), 'hash bool');
|
21 | assert.ok(validSha1.test(hash(true)), 'hash bool');
|
22 | assert.ok(validSha1.test(hash(func)), 'hash function');
|
23 | assert.ok(validSha1.test(hash(asyncFunc)), 'hash async function');
|
24 | });
|
25 |
|
26 | it('hashes special object types', function() {
|
27 | var dt = new Date();
|
28 | dt.setDate(dt.getDate() + 1);
|
29 |
|
30 | assert.ok(validSha1.test(hash([1,2,3,4])), 'hash array');
|
31 | assert.notEqual(hash([1,2,3,4]), hash([4,3,2,1]), 'different arrays not equal');
|
32 | assert.ok(validSha1.test(hash(new Date())), 'hash date');
|
33 | assert.notEqual(hash(new Date()), hash(dt), 'different dates not equal');
|
34 | assert.ok(validSha1.test(hash(null)), 'hash Null');
|
35 | assert.ok(validSha1.test(hash(Number.NaN)), 'hash NaN');
|
36 | assert.ok(validSha1.test(hash({ foo: undefined })), 'hash Undefined value');
|
37 | assert.ok(validSha1.test(hash(new RegExp())), 'hash regex');
|
38 | assert.ok(validSha1.test(hash(new Error())), 'hash error');
|
39 | });
|
40 |
|
41 | it('hashes node.js-internal object types', function() {
|
42 | if (typeof process !== 'undefined') {
|
43 | assert.ok(validSha1.test(hash(process)), 'hash process');
|
44 | }
|
45 |
|
46 | var timer = setTimeout(function() {}, 0);
|
47 | assert.ok(validSha1.test(hash(timer)), 'hash timer');
|
48 | });
|
49 |
|
50 | if (typeof Symbol !== 'undefined') {
|
51 | it('hashes Symbols', function() {
|
52 | assert.ok(validSha1.test(hash(Symbol('Banana'))), 'hash error');
|
53 | });
|
54 | }
|
55 |
|
56 | if (typeof Buffer !== 'undefined') {
|
57 | it("Buffers can be hashed", function() {
|
58 | assert.ok(validSha1.test(hash(new Buffer('Banana'))), 'hashes Buffers');
|
59 | });
|
60 | }
|
61 |
|
62 | if (typeof Uint8Array !== 'undefined') {
|
63 | it("Typed arrays can be hashed", function() {
|
64 |
|
65 | assert.ok(validSha1.test(hash(new Uint8Array([1,2,3,4]))), 'hashes Uint8Array');
|
66 | assert.ok(validSha1.test(hash(new Int8Array([1,2,3,4]))), 'hashes Int8Array');
|
67 | assert.ok(validSha1.test(hash(new Uint16Array([1,2,3,4]))), 'hashes Uint16Array');
|
68 | assert.ok(validSha1.test(hash(new Int16Array([1,2,3,4]))), 'hashes Int16Array');
|
69 | assert.ok(validSha1.test(hash(new Uint32Array([1,2,3,4]))), 'hashes Uint32Array');
|
70 | assert.ok(validSha1.test(hash(new Int32Array([1,2,3,4]))), 'hashes Int32Array');
|
71 | assert.ok(validSha1.test(hash(new Float32Array([1,2,3,4]))), 'hashes Float32Array');
|
72 | if (typeof Float64Array !== 'undefined')
|
73 | assert.ok(validSha1.test(hash(new Float64Array([1,2,3,4]))), 'hashes Float64Array');
|
74 | if (typeof Uint8ClampedArray !== 'undefined')
|
75 | assert.ok(validSha1.test(hash(new Uint8ClampedArray([1,2,3,4]))), 'hashes Uint8ClampedArray');
|
76 | assert.ok(validSha1.test(hash(new Uint8Array([1,2,3,4]).buffer)), 'hashes ArrayBuffer');
|
77 | });
|
78 | }
|
79 |
|
80 | if (typeof Map !== 'undefined') {
|
81 | it("Maps can be hashed", function() {
|
82 | var map = new Map([['a',1],['b',2]]);
|
83 | assert.ok(validSha1.test(hash(map)), 'hashes Maps');
|
84 | });
|
85 | }
|
86 |
|
87 | if (typeof WeakMap !== 'undefined') {
|
88 | it("WeakMaps can’t be hashed", function() {
|
89 | var map = new WeakMap([[{foo: 'bar'},1]]);
|
90 | assert.throws(function() {
|
91 | validSha1.test(hash(map))
|
92 | }, 'does not hash WeakMaps');
|
93 | });
|
94 | }
|
95 |
|
96 | if (typeof Set !== 'undefined') {
|
97 | it("Sets can be hashed", function() {
|
98 | var set = new Set(['you', 'du', 'tu', 'あなた', '您']);
|
99 | assert.ok(validSha1.test(hash(set)), 'hashes Sets');
|
100 | });
|
101 | }
|
102 |
|
103 | if (typeof WeakSet !== 'undefined') {
|
104 | it("WeakSets can’t be hashed", function() {
|
105 | var obj = {foo: 'bar'};
|
106 | var set = new WeakSet([obj]);
|
107 | assert.throws(function() {
|
108 | validSha1.test(hash(set))
|
109 | }, 'does not hash WeakSets');
|
110 | });
|
111 | }
|
112 |
|
113 | it("Builtin types themselves can be hashed", function() {
|
114 | var hashcount = {};
|
115 | var types = [Object, Date, Number, String, Function, RegExp,
|
116 | Error, 0, null, NaN];
|
117 | if (typeof WeakSet !== 'undefined') types.push(WeakSet);
|
118 | if (typeof Set !== 'undefined') types.push(Set);
|
119 | if (typeof WeakMap !== 'undefined') types.push(WeakMap);
|
120 | if (typeof Map !== 'undefined') types.push(Map);
|
121 | if (typeof Symbol !== 'undefined') types.push(Symbol);
|
122 | if (typeof Uint8Array !== 'undefined') types.push(Uint8Array);
|
123 |
|
124 |
|
125 | for (var idx in types) {
|
126 | var h = hash(types[idx]);
|
127 | assert.ok(validSha1.test(h));
|
128 | hashcount[h] = (hashcount[h] || 0) + 1;
|
129 | }
|
130 |
|
131 |
|
132 | var no = 0;
|
133 | for (var h in hashcount) {
|
134 | assert.equal(hashcount[h], 1);
|
135 | no++;
|
136 | }
|
137 |
|
138 |
|
139 | assert.equal(no, types.length);
|
140 | });
|
141 |
|
142 | it("Builtin types might result in identical hashes with respectFunctionNames = false", function() {
|
143 | var hashcount = {};
|
144 | var types = [Object, Date, Number, String, Function, RegExp,
|
145 | Error, 0, null, NaN];
|
146 | if (typeof WeakSet !== 'undefined') types.push(WeakSet);
|
147 | if (typeof Set !== 'undefined') types.push(Set);
|
148 | if (typeof WeakMap !== 'undefined') types.push(WeakMap);
|
149 | if (typeof Map !== 'undefined') types.push(Map);
|
150 | if (typeof Symbol !== 'undefined') types.push(Symbol);
|
151 | if (typeof Uint8Array !== 'undefined') types.push(Uint8Array);
|
152 |
|
153 |
|
154 | for (var idx in types) {
|
155 | var h = hash(types[idx], { respectFunctionNames: false });
|
156 | assert.ok(validSha1.test(h));
|
157 | hashcount[h] = (hashcount[h] || 0) + 1;
|
158 | }
|
159 |
|
160 |
|
161 | var no = 0;
|
162 | for (var h in hashcount) {
|
163 | assert.ok(hashcount[h] >= 1);
|
164 | no += hashcount[h];
|
165 | }
|
166 |
|
167 |
|
168 | assert.equal(no, types.length);
|
169 | });
|
170 |
|
171 | it("Functions with identical bodies and different names result in identical hashes with respectFunctionNames = false", function() {
|
172 | var fn1 = function a() {};
|
173 | var fn2 = function b() {};
|
174 | var toStringDummy = function() { return '...'; };
|
175 | fn1.toString = toStringDummy;
|
176 | fn2.toString = toStringDummy;
|
177 |
|
178 | var h1 = hash(fn1, { respectFunctionNames: false });
|
179 | var h2 = hash(fn2, { respectFunctionNames: false });
|
180 | assert.strictEqual(h1, h2);
|
181 | });
|
182 | });
|