1import { EventEmitter } from 'fbemitter'; 2import { Linking } from 'react-native'; 3 4const allOriginalPropertyDescriptors = new Map(); 5 6export function mockProperty(object, property, mockValue) { 7 // Save a reference to the original property descriptor 8 if (!allOriginalPropertyDescriptors.has(object)) { 9 allOriginalPropertyDescriptors.set(object, new Map()); 10 } 11 let descriptor = Object.getOwnPropertyDescriptor(object, property); 12 allOriginalPropertyDescriptors.get(object).set(property, descriptor); 13 14 // Select fields to inherit from the original descriptor 15 if (descriptor) { 16 const { configurable, enumerable, writable } = descriptor; 17 descriptor = { configurable, enumerable, writable }; 18 } 19 20 Object.defineProperty(object, property, { 21 configurable: true, 22 enumerable: true, 23 writable: true, 24 ...descriptor, 25 value: mockValue, 26 }); 27} 28 29export function unmockProperty(object, property) { 30 const descriptors = allOriginalPropertyDescriptors.get(object); 31 if (!descriptors || !descriptors.has(property)) { 32 return; 33 } 34 35 const descriptor = descriptors.get(property); 36 if (descriptor) { 37 Object.defineProperty(object, property, descriptor); 38 } else { 39 delete object[property]; 40 } 41 42 // Clean up the reference 43 descriptors.delete(property); 44 if (!descriptors.size) { 45 allOriginalPropertyDescriptors.delete(object); 46 } 47} 48 49export function unmockAllProperties() { 50 for (const [object, descriptors] of allOriginalPropertyDescriptors) { 51 for (const [property, descriptor] of descriptors) { 52 if (descriptor) { 53 Object.defineProperty(object, property, descriptor); 54 } else { 55 delete object[property]; 56 } 57 } 58 } 59 allOriginalPropertyDescriptors.clear(); 60} 61 62export function mockLinking() { 63 const emitter = new EventEmitter(); 64 const subscriptions = {}; 65 66 mockProperty( 67 Linking, 68 'addEventListener', 69 jest.fn((type, cb) => { 70 const subscription = emitter.addListener(type, cb); 71 subscriptions[type] = subscriptions[type] || new Map(); 72 subscriptions[type].set(cb, subscription); 73 return subscription; 74 }) 75 ); 76 77 mockProperty( 78 Linking, 79 'removeEventListener', 80 jest.fn((type, cb) => { 81 subscriptions[type].delete(cb); 82 }) 83 ); 84 85 return (type, data) => { 86 emitter.emit(type, data); 87 }; 88} 89