1 | import * as Utils from '../utils';
|
2 |
|
3 | describe('Utils', () => {
|
4 | describe('mapToCssModules', () => {
|
5 | describe('without css module', () => {
|
6 | it('should return a string', () => {
|
7 | expect(Utils.mapToCssModules('btn btn-primary')).toEqual(
|
8 | expect.any(String),
|
9 | );
|
10 | });
|
11 |
|
12 | it('should return the classnames it was given, unchanged', () => {
|
13 | expect(Utils.mapToCssModules('btn btn-primary')).toBe(
|
14 | 'btn btn-primary',
|
15 | );
|
16 | });
|
17 | });
|
18 |
|
19 | describe('with css module', () => {
|
20 | it('should return a string', () => {
|
21 | const cssModule = {
|
22 | btn: 'a1',
|
23 | 'btn-success': 'b1',
|
24 | 'btn-primary': 'c2',
|
25 | };
|
26 | expect(Utils.mapToCssModules('btn btn-primary', cssModule)).toEqual(
|
27 | expect.any(String),
|
28 | );
|
29 | });
|
30 |
|
31 | it('should return the mapped classnames', () => {
|
32 | const cssModule = {
|
33 | btn: 'a1',
|
34 | 'btn-success': 'b1',
|
35 | 'btn-primary': 'c2',
|
36 | };
|
37 | expect(Utils.mapToCssModules('btn btn-primary', cssModule)).toBe(
|
38 | 'a1 c2',
|
39 | );
|
40 | });
|
41 |
|
42 | it('should return the original classname when it is not in the map', () => {
|
43 | const cssModule = {
|
44 | btn: 'a1',
|
45 | 'btn-success': 'b1',
|
46 | };
|
47 | expect(Utils.mapToCssModules('btn btn-primary', cssModule)).toBe(
|
48 | 'a1 btn-primary',
|
49 | );
|
50 | });
|
51 | });
|
52 | });
|
53 |
|
54 | describe('omit', () => {
|
55 | it('should omit keys', () => {
|
56 | const input = {
|
57 | hello: 'world',
|
58 | speed: 'fast',
|
59 | size: 'small',
|
60 | };
|
61 | expect(Utils.omit(input, ['hello'])).toEqual({
|
62 | speed: 'fast',
|
63 | size: 'small',
|
64 | });
|
65 | });
|
66 |
|
67 | it('should not alter source object', () => {
|
68 | const input = {
|
69 | hello: 'world',
|
70 | speed: 'fast',
|
71 | size: 'small',
|
72 | };
|
73 | expect(Utils.omit(input, ['hello'])).toEqual({
|
74 | speed: 'fast',
|
75 | size: 'small',
|
76 | });
|
77 | expect(input).toEqual({
|
78 | hello: 'world',
|
79 | speed: 'fast',
|
80 | size: 'small',
|
81 | });
|
82 | });
|
83 |
|
84 | it('should ignore non-existing keys', () => {
|
85 | const input = {
|
86 | hello: 'world',
|
87 | speed: 'fast',
|
88 | size: 'small',
|
89 | };
|
90 | expect(Utils.omit(input, ['non-existing', 'hello'])).toEqual({
|
91 | speed: 'fast',
|
92 | size: 'small',
|
93 | });
|
94 | });
|
95 |
|
96 | it('should return a new object', () => {
|
97 | const input = {
|
98 | hello: 'world',
|
99 | };
|
100 |
|
101 | expect(Utils.omit(input, [])).not.toBe(input);
|
102 | });
|
103 | });
|
104 |
|
105 | describe('DOMElement', () => {
|
106 | it('should not return an error when the prop is an instance of an Element', () => {
|
107 | const props = {
|
108 | dom: document.createElement('div'),
|
109 | };
|
110 | const propName = 'dom';
|
111 | const componentName = 'ComponentName';
|
112 |
|
113 | expect(Utils.DOMElement(props, propName, componentName)).toBeUndefined();
|
114 | });
|
115 |
|
116 | it('should return an error when the prop is NOT an instance of an Element', () => {
|
117 | const props = {
|
118 | dom: 'not an Element',
|
119 | };
|
120 | const propName = 'dom';
|
121 | const componentName = 'ComponentName';
|
122 |
|
123 | expect(Utils.DOMElement(props, propName, componentName)).toEqual(
|
124 | new Error(
|
125 | 'Invalid prop `' +
|
126 | propName +
|
127 | '` supplied to `' +
|
128 | componentName +
|
129 | '`. Expected prop to be an instance of Element. Validation failed.',
|
130 | ),
|
131 | );
|
132 | });
|
133 | });
|
134 |
|
135 | describe('getTarget', () => {
|
136 | it('should return the result of target if target is a function', () => {
|
137 | const data = {};
|
138 | const spy = jest.fn(() => data);
|
139 | expect(Utils.getTarget(spy)).toEqual(data);
|
140 | expect(spy).toHaveBeenCalled();
|
141 | });
|
142 |
|
143 | it('should return all matching elements if allElement param is true', () => {
|
144 | const element = document.createElement('div');
|
145 | element.innerHTML = `<span class='example'>span 1</span>
|
146 | <span class='example'>span 2</span>`;
|
147 | document.body.appendChild(element);
|
148 |
|
149 | jest.spyOn(document, 'querySelectorAll');
|
150 | const elements = Utils.getTarget('.example', true);
|
151 | expect(elements.length).toEqual(2);
|
152 | expect(elements[1].textContent).toEqual('span 2');
|
153 | expect(document.querySelectorAll).toHaveBeenCalledWith('.example');
|
154 | document.querySelectorAll.mockRestore();
|
155 | });
|
156 |
|
157 | it('should return elements as array like object if allElement param is true', () => {
|
158 | const data = {};
|
159 | const spy = jest.fn(() => data);
|
160 | const elements = Utils.getTarget(spy, true);
|
161 | expect(elements).toHaveProperty('length');
|
162 | expect(elements).toContain(data);
|
163 | expect(spy).toHaveBeenCalled();
|
164 | });
|
165 |
|
166 | it('should query the document for the target if the target is a string', () => {
|
167 | const element = document.createElement('div');
|
168 | element.className = 'thing';
|
169 | document.body.appendChild(element);
|
170 | jest.spyOn(document, 'querySelectorAll');
|
171 | expect(Utils.getTarget('.thing')).toEqual(element);
|
172 | expect(document.querySelectorAll).toHaveBeenCalledWith('.thing');
|
173 | document.querySelectorAll.mockRestore();
|
174 | });
|
175 |
|
176 | it('should query the document for the id target if the target is a string and could not be found normally', () => {
|
177 | const element = document.createElement('div');
|
178 | element.setAttribute('id', 'thing');
|
179 | document.body.appendChild(element);
|
180 | jest.spyOn(document, 'querySelectorAll');
|
181 | expect(Utils.getTarget('thing')).toEqual(element);
|
182 | expect(document.querySelectorAll).toHaveBeenCalledWith('#thing');
|
183 | document.querySelectorAll.mockRestore();
|
184 | });
|
185 |
|
186 | it('should return the input target if it is not a function nor a string', () => {
|
187 | const target = {};
|
188 | expect(Utils.getTarget(target)).toEqual(target);
|
189 | });
|
190 |
|
191 | it('should not return an error when the target could be identified', () => {
|
192 | const element = document.createElement('div');
|
193 | element.className = 'thing';
|
194 | document.body.appendChild(element);
|
195 | jest.spyOn(document, 'querySelector');
|
196 | expect(() => {
|
197 | Utils.getTarget('.thing');
|
198 | }).not.toThrow();
|
199 | });
|
200 |
|
201 | it('should return an error when the target could not be identified', () => {
|
202 | const target = 'not a target';
|
203 | expect(() => {
|
204 | Utils.getTarget(target);
|
205 | }).toThrow(
|
206 | `The target '${target}' could not be identified in the dom, tip: check spelling`,
|
207 | );
|
208 | });
|
209 |
|
210 | it('should return the value of the `current` object if it is a react Ref object', () => {
|
211 | const target = { current: { name: 'hello' } };
|
212 | expect(Utils.getTarget(target)).toEqual(target.current);
|
213 | });
|
214 |
|
215 | it('should return null if the `current` property of the target is null', () => {
|
216 | const target = { current: null };
|
217 | expect(Utils.getTarget(target)).toBeNull();
|
218 | expect(Utils.getTarget(target, true)).toStrictEqual([]);
|
219 | });
|
220 | });
|
221 |
|
222 | describe('setGlobalCssModule', () => {
|
223 | it('should return the mapped classnames', () => {
|
224 | const globalCssModule = {
|
225 | btn: 'a1',
|
226 | 'btn-success': 'b1',
|
227 | 'btn-primary': 'c2',
|
228 | };
|
229 | Utils.setGlobalCssModule(globalCssModule);
|
230 | expect(Utils.mapToCssModules('btn btn-primary')).toBe('a1 c2');
|
231 | });
|
232 | });
|
233 |
|
234 | describe('isFunction', () => {
|
235 | it('should return `true` for functions', () => {
|
236 | function test() {}
|
237 |
|
238 | expect(Utils.isFunction(test)).toBe(true);
|
239 | expect(Utils.isFunction(Array.prototype.slice)).toBe(true);
|
240 | });
|
241 |
|
242 | it('should return `true` for async functions', () => {
|
243 | async function asyncFunc() {}
|
244 |
|
245 | expect(Utils.isFunction(asyncFunc)).toEqual(
|
246 | typeof asyncFunc === 'function',
|
247 | );
|
248 | });
|
249 |
|
250 | it('should return `true` for generator functions', () => {
|
251 | function* genFunc() {}
|
252 |
|
253 | expect(Utils.isFunction(genFunc)).toEqual(typeof genFunc === 'function');
|
254 | });
|
255 |
|
256 | it('should return `false` for non-functions', () => {
|
257 | function toArgs(array) {
|
258 | return function () {
|
259 | return arguments;
|
260 | }.apply(undefined, array);
|
261 | }
|
262 |
|
263 | expect(Utils.isFunction(toArgs([1, 2, 3]))).toBe(false);
|
264 | expect(Utils.isFunction([1, 2, 3])).toBe(false);
|
265 | expect(Utils.isFunction(true)).toBe(false);
|
266 | expect(Utils.isFunction(new Date())).toBe(false);
|
267 | expect(Utils.isFunction(new Error())).toBe(false);
|
268 | expect(Utils.isFunction({ a: 1 })).toBe(false);
|
269 | expect(Utils.isFunction(1)).toBe(false);
|
270 | expect(Utils.isFunction(/x/)).toBe(false);
|
271 | expect(Utils.isFunction('a')).toBe(false);
|
272 | expect(Utils.isFunction(Symbol('a'))).toBe(false);
|
273 |
|
274 | if (document) {
|
275 | expect(Utils.isFunction(document.getElementsByTagName('body'))).toBe(
|
276 | false,
|
277 | );
|
278 | }
|
279 | });
|
280 | });
|
281 |
|
282 | describe('isObject', () => {
|
283 | it('should return `true` for objects', () => {
|
284 | expect(Utils.isObject([1, 2, 3])).toBe(true);
|
285 | expect(Utils.isObject(Object(false))).toBe(true);
|
286 | expect(Utils.isObject(new Date())).toBe(true);
|
287 | expect(Utils.isObject(new Error())).toBe(true);
|
288 | expect(Utils.isObject({ a: 1 })).toBe(true);
|
289 | expect(Utils.isObject({ a: 1 })).toBe(true);
|
290 | expect(Utils.isObject(Object(0))).toBe(true);
|
291 | expect(Utils.isObject(/x/)).toBe(true);
|
292 | expect(Utils.isObject(Object('a'))).toBe(true);
|
293 | if (document) {
|
294 | expect(Utils.isObject(document.body)).toBe(true);
|
295 | }
|
296 | });
|
297 |
|
298 | it('should return `false` for non-objects', () => {
|
299 | expect(Utils.isObject(0)).toBe(false);
|
300 | expect(Utils.isObject(false)).toBe(false);
|
301 | expect(Utils.isObject(1)).toBe(false);
|
302 | });
|
303 | });
|
304 |
|
305 | describe('toNumber', () => {
|
306 | it('should return number', () => {
|
307 | expect(Utils.toNumber('5')).toEqual(5);
|
308 | expect(Utils.toNumber('5.0')).toEqual(5);
|
309 | expect(Utils.toNumber('1.1')).toEqual(1.1);
|
310 | expect(Utils.toNumber('-1.1')).toEqual(-1.1);
|
311 | expect(Utils.toNumber(0 / 0)).toEqual(NaN);
|
312 | expect(Utils.toNumber(0)).toEqual(0);
|
313 | });
|
314 | });
|
315 |
|
316 | describe('addDefaultProps', () => {
|
317 | it('should return an object', () => {
|
318 | const defaultProps = {
|
319 | a: 1,
|
320 | b: 2,
|
321 | c: 3,
|
322 | };
|
323 | const props = {
|
324 | a: 4,
|
325 | b: 5,
|
326 | };
|
327 | expect(Utils.addDefaultProps(defaultProps, props)).toEqual(
|
328 | expect.any(Object),
|
329 | );
|
330 | });
|
331 |
|
332 | it('should return an object with default props', () => {
|
333 | const defaultProps = {
|
334 | a: 1,
|
335 | b: 2,
|
336 | c: 3,
|
337 | d: {
|
338 | e: 4,
|
339 | f: 5,
|
340 | },
|
341 | };
|
342 | const props = {
|
343 | a: 4,
|
344 | b: 5,
|
345 | d: {
|
346 | e: 6,
|
347 | f: 5,
|
348 | },
|
349 | };
|
350 | expect(Utils.addDefaultProps(defaultProps, props)).toEqual({
|
351 | a: 4,
|
352 | b: 5,
|
353 | c: 3,
|
354 | d: {
|
355 | e: 6,
|
356 | f: 5,
|
357 | },
|
358 | });
|
359 | });
|
360 | });
|
361 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
376 |
|
377 |
|
378 |
|
379 |
|
380 |
|
381 |
|
382 |
|
383 |
|
384 |
|
385 |
|
386 |
|
387 |
|
388 |
|
389 |
|
390 |
|
391 |
|
392 |
|
393 |
|
394 |
|
395 |
|
396 |
|
397 |
|
398 |
|
399 | });
|