|
14 | 14 | * permissions and limitations under the License. |
15 | 15 | */ |
16 | 16 |
|
| 17 | +import computeHash from 'object-hash'; |
17 | 18 | import { computeKey } from '../src/computeKey'; |
18 | 19 |
|
| 20 | +jest.mock('object-hash', () => { |
| 21 | + const originalComputeHash = jest.requireActual('object-hash'); |
| 22 | + return jest.fn(originalComputeHash); |
| 23 | +}); |
| 24 | + |
19 | 25 | describe('computeKey', () => { |
| 26 | + beforeEach(() => { |
| 27 | + jest.clearAllMocks(); |
| 28 | + }); |
20 | 29 | it('should return an object', () => { |
21 | 30 | expect(computeKey('abcd', {})).toMatchInlineSnapshot(` |
22 | 31 | Object { |
@@ -58,4 +67,54 @@ describe('computeKey', () => { |
58 | 67 | }; |
59 | 68 | expect(computeKey('uri', firstOptions).hash).toBe(computeKey('uri', secondOptions).hash); |
60 | 69 | }); |
| 70 | + |
| 71 | + it('should return a different, stable hash, if the option mapKeyToCacheKey is passed', () => { |
| 72 | + const key = 'abcd'; |
| 73 | + const mappedKey = 'efgh'; |
| 74 | + const { hash: mappedHash1 } = computeKey(key, { mapKeyToCacheKey: () => mappedKey }); |
| 75 | + const { hash: mappedHash2 } = computeKey(key, { mapKeyToCacheKey: () => mappedKey }); |
| 76 | + |
| 77 | + const { hash: unmappedHash } = computeKey(key, {}); |
| 78 | + |
| 79 | + expect(mappedHash1).toBe(mappedHash2); |
| 80 | + expect(mappedHash1).not.toBe(unmappedHash); |
| 81 | + }); |
| 82 | + |
| 83 | + it('should return the same key if the option mapKeyToCacheKey returns the same string as the key', () => { |
| 84 | + const key = 'abcd'; |
| 85 | + const { hash: mappedHash } = computeKey(key, { mapKeyToCacheKey: (_key) => _key }); |
| 86 | + |
| 87 | + const { hash: unmappedHash } = computeKey(key, {}); |
| 88 | + |
| 89 | + expect(mappedHash).toBe(unmappedHash); |
| 90 | + }); |
| 91 | + |
| 92 | + it('should pass generated cacheKey to the underlying hash function along with the options, and return the un-mapped key to the caller', () => { |
| 93 | + const computedKey = computeKey(() => 'abcd', { |
| 94 | + mapKeyToCacheKey: (key, options) => `${key.toUpperCase()}-${options.optionKeyMock}`, |
| 95 | + optionKeyMock: 'optionKeyValue', |
| 96 | + }); |
| 97 | + expect(computedKey.key).toBe('abcd'); |
| 98 | + expect(computeHash).toHaveBeenCalledWith(['ABCD-optionKeyValue', { optionKeyMock: 'optionKeyValue' }], { respectType: false }); |
| 99 | + }); |
| 100 | + |
| 101 | + it('should return false if mapKeyToCacheKey throws error', () => { |
| 102 | + expect( |
| 103 | + computeKey(() => 'abcd', { |
| 104 | + mapKeyToCacheKey: () => { |
| 105 | + throw new Error('error'); |
| 106 | + }, |
| 107 | + }) |
| 108 | + ).toEqual(false); |
| 109 | + }); |
| 110 | + |
| 111 | + it('should return false if mapKeyToCacheKey returns false', () => { |
| 112 | + expect(computeKey(() => 'abcd', { mapKeyToCacheKey: () => false })).toEqual(false); |
| 113 | + }); |
| 114 | + |
| 115 | + it('should throw an error if mapKeyToCacheKey is defined and not a function', () => { |
| 116 | + expect(() => computeKey(() => 'abcd', |
| 117 | + { mapKeyToCacheKey: 'string' } |
| 118 | + )).toThrow('mapKeyToCacheKey must be a function'); |
| 119 | + }); |
61 | 120 | }); |
0 commit comments