blob: 7c40ed5c9d96df4e9f05c9bdc08fee9d112e4732 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import {assert} from 'chai';
6import {arrayDifference, setHasAny, capitalizeFirst, hasPrefix, objectToMap,
7 objectValuesForKeys, equalsIgnoreCase, immutableSplice, userIsMember,
8 urlWithNewParams, createObjectComparisonFunc} from './helpers.js';
9
10
11describe('arrayDifference', () => {
12 it('empty array stays empty', () => {
13 assert.deepEqual(arrayDifference([], []), []);
14 assert.deepEqual(arrayDifference([], undefined), []);
15 assert.deepEqual(arrayDifference([], ['a']), []);
16 });
17
18 it('subtracting empty array does nothing', () => {
19 assert.deepEqual(arrayDifference(['a'], []), ['a']);
20 assert.deepEqual(arrayDifference([1, 2, 3], []), [1, 2, 3]);
21 assert.deepEqual(arrayDifference([1, 2, 'test'], []), [1, 2, 'test']);
22 assert.deepEqual(arrayDifference([1, 2, 'test'], undefined),
23 [1, 2, 'test']);
24 });
25
26 it('subtracts elements from array', () => {
27 assert.deepEqual(arrayDifference(['a', 'b', 'c'], ['b', 'c']), ['a']);
28 assert.deepEqual(arrayDifference(['a', 'b', 'c'], ['a']), ['b', 'c']);
29 assert.deepEqual(arrayDifference(['a', 'b', 'c'], ['b']), ['a', 'c']);
30 assert.deepEqual(arrayDifference([1, 2, 3], [2]), [1, 3]);
31 });
32
33 it('does not subtract missing elements from array', () => {
34 assert.deepEqual(arrayDifference(['a', 'b', 'c'], ['d']), ['a', 'b', 'c']);
35 assert.deepEqual(arrayDifference([1, 2, 3], [5]), [1, 2, 3]);
36 assert.deepEqual(arrayDifference([1, 2, 3], [-1, 2]), [1, 3]);
37 });
38
39 it('custom equals function', () => {
40 assert.deepEqual(arrayDifference(['a', 'b'], ['A']), ['a', 'b']);
41 assert.deepEqual(arrayDifference(['a', 'b'], ['A'], equalsIgnoreCase),
42 ['b']);
43 });
44});
45
46describe('setHasAny', () => {
47 it('empty set never has any values', () => {
48 assert.isFalse(setHasAny(new Set(), []));
49 assert.isFalse(setHasAny(new Set(), ['test']));
50 assert.isFalse(setHasAny(new Set(), ['nope', 'yup', 'no']));
51 });
52
53 it('false when no values found', () => {
54 assert.isFalse(setHasAny(new Set(['hello', 'world']), []));
55 assert.isFalse(setHasAny(new Set(['hello', 'world']), ['wor']));
56 assert.isFalse(setHasAny(new Set(['test']), ['other', 'values']));
57 assert.isFalse(setHasAny(new Set([1, 2, 3]), [4, 5, 6]));
58 });
59
60 it('true when values found', () => {
61 assert.isTrue(setHasAny(new Set(['hello', 'world']), ['world']));
62 assert.isTrue(setHasAny(new Set([1, 2, 3]), [3, 4, 5]));
63 assert.isTrue(setHasAny(new Set([1, 2, 3]), [1, 3]));
64 });
65});
66
67describe('capitalizeFirst', () => {
68 it('empty string', () => {
69 assert.equal(capitalizeFirst(''), '');
70 });
71
72 it('ignores non-letters', () => {
73 assert.equal(capitalizeFirst('8fcsdf'), '8fcsdf');
74 });
75
76 it('preserves existing caps', () => {
77 assert.equal(capitalizeFirst('HELLO world'), 'HELLO world');
78 });
79
80 it('capitalizes lowercase', () => {
81 assert.equal(capitalizeFirst('hello world'), 'Hello world');
82 });
83});
84
85describe('hasPrefix', () => {
86 it('only true when has prefix', () => {
87 assert.isFalse(hasPrefix('teststring', 'test-'));
88 assert.isFalse(hasPrefix('stringtest-', 'test-'));
89 assert.isFalse(hasPrefix('^test-$', 'test-'));
90 assert.isTrue(hasPrefix('test-', 'test-'));
91 assert.isTrue(hasPrefix('test-fsdfsdf', 'test-'));
92 });
93
94 it('ignores case when checking prefix', () => {
95 assert.isTrue(hasPrefix('TEST-string', 'test-'));
96 assert.isTrue(hasPrefix('test-string', 'test-'));
97 assert.isTrue(hasPrefix('tEsT-string', 'test-'));
98 });
99});
100
101describe('objectToMap', () => {
102 it('converts Object to Map with the same keys', () => {
103 assert.deepEqual(objectToMap({}), new Map());
104 assert.deepEqual(objectToMap({test: 'value'}),
105 new Map([['test', 'value']]));
106 assert.deepEqual(objectToMap({['weird:key']: 'value',
107 ['what is this key']: 'v2'}), new Map([['weird:key', 'value'],
108 ['what is this key', 'v2']]));
109 });
110});
111
112describe('objectValuesForKeys', () => {
113 it('no values when no matching keys', () => {
114 assert.deepEqual(objectValuesForKeys({}, []), []);
115 assert.deepEqual(objectValuesForKeys({}, []), []);
116 assert.deepEqual(objectValuesForKeys({key: 'value'}, []), []);
117 });
118
119 it('returns values when keys match', () => {
120 assert.deepEqual(objectValuesForKeys({a: 1, b: 2, c: 3}, ['a', 'b']),
121 [1, 2]);
122 assert.deepEqual(objectValuesForKeys({a: 1, b: 2, c: 3}, ['b', 'c']),
123 [2, 3]);
124 assert.deepEqual(objectValuesForKeys({['weird:key']: {nested: 'obj'}},
125 ['weird:key']), [{nested: 'obj'}]);
126 });
127
128 it('sets non-matching keys to undefined', () => {
129 assert.deepEqual(objectValuesForKeys({a: 1, b: 2, c: 3}, ['c', 'd', 'e']),
130 [3, undefined, undefined]);
131 assert.deepEqual(objectValuesForKeys({a: 1, b: 2, c: 3}, [1, 2, 3]),
132 [undefined, undefined, undefined]);
133 });
134});
135
136describe('equalsIgnoreCase', () => {
137 it('matches same case strings', () => {
138 assert.isTrue(equalsIgnoreCase('', ''));
139 assert.isTrue(equalsIgnoreCase('HelloWorld', 'HelloWorld'));
140 assert.isTrue(equalsIgnoreCase('hmm', 'hmm'));
141 assert.isTrue(equalsIgnoreCase('TEST', 'TEST'));
142 });
143
144 it('matches different case strings', () => {
145 assert.isTrue(equalsIgnoreCase('a', 'A'));
146 assert.isTrue(equalsIgnoreCase('HelloWorld', 'helloworld'));
147 assert.isTrue(equalsIgnoreCase('hmm', 'HMM'));
148 assert.isTrue(equalsIgnoreCase('TEST', 'teSt'));
149 });
150
151 it('does not match different strings', () => {
152 assert.isFalse(equalsIgnoreCase('hello', 'hello '));
153 assert.isFalse(equalsIgnoreCase('superstring', 'string'));
154 assert.isFalse(equalsIgnoreCase('aaa', 'aa'));
155 });
156});
157
158describe('immutableSplice', () => {
159 it('does not edit original array', () => {
160 const arr = ['apples', 'pears', 'oranges'];
161
162 assert.deepEqual(immutableSplice(arr, 1, 1),
163 ['apples', 'oranges']);
164
165 assert.deepEqual(arr, ['apples', 'pears', 'oranges']);
166 });
167
168 it('removes multiple items', () => {
169 const arr = [1, 2, 3, 4, 5, 6];
170
171 assert.deepEqual(immutableSplice(arr, 1, 0), [1, 2, 3, 4, 5, 6]);
172 assert.deepEqual(immutableSplice(arr, 1, 4), [1, 6]);
173 assert.deepEqual(immutableSplice(arr, 0, 6), []);
174 });
175
176 it('adds items', () => {
177 const arr = [1, 2, 3];
178
179 assert.deepEqual(immutableSplice(arr, 1, 1, 4, 5, 6), [1, 4, 5, 6, 3]);
180 assert.deepEqual(immutableSplice(arr, 2, 1, 4, 5, 6), [1, 2, 4, 5, 6]);
181 assert.deepEqual(immutableSplice(arr, 0, 0, -3, -2, -1, 0),
182 [-3, -2, -1, 0, 1, 2, 3]);
183 });
184});
185
186describe('urlWithNewParams', () => {
187 it('empty', () => {
188 assert.equal(urlWithNewParams(), '');
189 assert.equal(urlWithNewParams(''), '');
190 assert.equal(urlWithNewParams('', {}), '');
191 assert.equal(urlWithNewParams('', {}, {}), '');
192 assert.equal(urlWithNewParams('', {}, {}, []), '');
193 });
194
195 it('preserves existing URL without changes', () => {
196 assert.equal(urlWithNewParams('/p/chromium/issues/list'),
197 '/p/chromium/issues/list');
198 assert.equal(urlWithNewParams('/p/chromium/issues/list', {q: 'owner:me'}),
199 '/p/chromium/issues/list?q=owner%3Ame');
200 assert.equal(
201 urlWithNewParams('/p/chromium/issues/list', {q: 'owner:me', can: '1'}),
202 '/p/chromium/issues/list?q=owner%3Ame&can=1');
203 });
204
205 it('adds new params', () => {
206 assert.equal(
207 urlWithNewParams('/p/chromium/issues/list', {}, {q: 'owner:me'}),
208 '/p/chromium/issues/list?q=owner%3Ame');
209 assert.equal(
210 urlWithNewParams('/p/chromium/issues/list',
211 {can: '1'}, {q: 'owner:me'}),
212 '/p/chromium/issues/list?can=1&q=owner%3Ame');
213
214 // Override existing params.
215 assert.equal(
216 urlWithNewParams('/p/chromium/issues/list',
217 {can: '1', q: 'owner:me'}, {q: 'test'}),
218 '/p/chromium/issues/list?can=1&q=test');
219 });
220
221 it('clears existing params', () => {
222 assert.equal(
223 urlWithNewParams('/p/chromium/issues/list', {q: 'owner:me'}, {}, ['q']),
224 '/p/chromium/issues/list');
225 assert.equal(
226 urlWithNewParams('/p/chromium/issues/list',
227 {can: '1'}, {q: 'owner:me'}, ['can']),
228 '/p/chromium/issues/list?q=owner%3Ame');
229 assert.equal(
230 urlWithNewParams('/p/chromium/issues/list', {q: 'owner:me'}, {can: '2'},
231 ['q', 'can', 'fakeparam']),
232 '/p/chromium/issues/list');
233 });
234});
235
236describe('userIsMember', () => {
237 it('false when no user', () => {
238 assert.isFalse(userIsMember(undefined));
239 assert.isFalse(userIsMember({}));
240 assert.isFalse(userIsMember({}, 'chromium',
241 new Map([['123', {ownerOf: ['chromium']}]])));
242 });
243
244 it('true when user is member of project', () => {
245 assert.isTrue(userIsMember({userId: '123'}, 'chromium',
246 new Map([['123', {contributorTo: ['chromium']}]])));
247
248 assert.isTrue(userIsMember({userId: '123'}, 'chromium',
249 new Map([['123', {ownerOf: ['chromium']}]])));
250
251 assert.isTrue(userIsMember({userId: '123'}, 'chromium',
252 new Map([['123', {memberOf: ['chromium']}]])));
253 });
254
255 it('true when user is member of multiple projects', () => {
256 assert.isTrue(userIsMember({userId: '123'}, 'chromium', new Map([
257 ['123', {contributorTo: ['test', 'chromium', 'fakeproject']}],
258 ])));
259
260 assert.isTrue(userIsMember({userId: '123'}, 'chromium', new Map([
261 ['123', {ownerOf: ['test', 'chromium', 'fakeproject']}],
262 ])));
263
264 assert.isTrue(userIsMember({userId: '123'}, 'chromium', new Map([
265 ['123', {memberOf: ['test', 'chromium', 'fakeproject']}],
266 ])));
267 });
268
269 it('false when user is member of different project', () => {
270 assert.isFalse(userIsMember({userId: '123'}, 'chromium', new Map([
271 ['123', {contributorTo: ['test', 'fakeproject']}],
272 ])));
273
274 assert.isFalse(userIsMember({userId: '123'}, 'chromium', new Map([
275 ['123', {ownerOf: ['test', 'fakeproject']}],
276 ])));
277
278 assert.isFalse(userIsMember({userId: '123'}, 'chromium', new Map([
279 ['123', {memberOf: ['test', 'fakeproject']}],
280 ])));
281 });
282
283 it('false when no project data for user', () => {
284 assert.isFalse(userIsMember({userId: '123'}, 'chromium'));
285 assert.isFalse(userIsMember({userId: '123'}, 'chromium', new Map()));
286 assert.isFalse(userIsMember({userId: '123'}, 'chromium', new Map([
287 ['543', {ownerOf: ['chromium']}],
288 ])));
289 });
290});
291
292describe('createObjectComparisonFunc', () => {
293 it('returns a function', () => {
294 const result = createObjectComparisonFunc(new Set());
295 assert.instanceOf(result, Function);
296 });
297
298 describe('returned function', () => {
299 it('returns false if both inputs are undefined', () => {
300 const comparableProps = new Set(['a', 'b', 'c']);
301 const func = createObjectComparisonFunc(comparableProps);
302 const result = func(undefined, undefined);
303
304 assert.isFalse(result);
305 });
306
307 it('returns true if only one inputs is undefined', () => {
308 const comparableProps = new Set(['a', 'b', 'c']);
309 const func = createObjectComparisonFunc(comparableProps);
310 const result = func({}, undefined);
311
312 assert.isTrue(result);
313 });
314
315 it('returns false if both inputs are null', () => {
316 const comparableProps = new Set(['a', 'b', 'c']);
317 const func = createObjectComparisonFunc(comparableProps);
318 const result = func(null, null);
319
320 assert.isFalse(result);
321 });
322
323 it('returns true if only one inputs is null', () => {
324 const comparableProps = new Set(['a', 'b', 'c']);
325 const func = createObjectComparisonFunc(comparableProps);
326 const result = func({}, null);
327
328 assert.isTrue(result);
329 });
330
331 it('returns true if any comparable property is different', () => {
332 const comparableProps = new Set(['a', 'b', 'c']);
333 const func = createObjectComparisonFunc(comparableProps);
334 const a = {a: 1, b: 2, c: 3};
335 const b = {a: 1, b: 2, c: '3'};
336 const result = func(a, b);
337
338 assert.isTrue(result);
339 });
340
341 it('returns false if all comparable properties are the same', () => {
342 const comparableProps = new Set(['a', 'b', 'c']);
343 const func = createObjectComparisonFunc(comparableProps);
344 const a = {a: 1, b: 2, c: 3};
345 const b = {a: 1, b: 2, c: 3};
346 const result = func(a, b);
347
348 assert.isFalse(result);
349 });
350
351 it('ignores non-comparable properties', () => {
352 const comparableProps = new Set(['a', 'b', 'c']);
353 const func = createObjectComparisonFunc(comparableProps);
354 const a = {a: 1, b: 2, c: 3, d: 4};
355 const b = {a: 1, b: 2, c: 3, d: 'not four', e: 'exists'};
356 const result = func(a, b);
357
358 assert.isFalse(result);
359 });
360 });
361});