import { Platform as PlatformExpo } from '@unimodules/core';
import { Linking, Platform } from 'react-native';
import { EventEmitter } from 'fbemitter';
const allOriginalPropertyDescriptors = new Map();
export function mockProperty(object, property, mockValue) {
// Save a reference to the original property descriptor
if (!allOriginalPropertyDescriptors.has(object)) {
allOriginalPropertyDescriptors.set(object, new Map());
}
let descriptor = Object.getOwnPropertyDescriptor(object, property);
allOriginalPropertyDescriptors.get(object).set(property, descriptor);
// Select fields to inherit from the original descriptor
if (descriptor) {
let { configurable, enumerable, writable } = descriptor;
descriptor = { configurable, enumerable, writable };
}
Object.defineProperty(object, property, {
configurable: true,
enumerable: true,
writable: true,
...descriptor,
value: mockValue,
});
}
export function unmockProperty(object, property) {
let descriptors = allOriginalPropertyDescriptors.get(object);
if (!descriptors || !descriptors.has(property)) {
return;
}
let descriptor = descriptors.get(property);
if (descriptor) {
Object.defineProperty(object, property, descriptor);
} else {
delete object[property];
}
// Clean up the reference
descriptors.delete(property);
if (!descriptors.size) {
allOriginalPropertyDescriptors.delete(object);
}
}
export function unmockAllProperties() {
for (let [object, descriptors] of allOriginalPropertyDescriptors) {
for (let [property, descriptor] of descriptors) {
if (descriptor) {
Object.defineProperty(object, property, descriptor);
} else {
delete object[property];
}
}
}
allOriginalPropertyDescriptors.clear();
}
export function mockPlatformIOS() {
mockProperty(Platform, 'OS', 'ios');
mockProperty(PlatformExpo, 'OS', 'ios');
}
export function mockPlatformAndroid() {
mockProperty(Platform, 'OS', 'android');
mockProperty(PlatformExpo, 'OS', 'android');
}
export function mockPlatformWeb() {
mockProperty(Platform, 'OS', 'web');
mockProperty(PlatformExpo, 'OS', 'web');
}
export function describeCrossPlatform(message, tests) {
describe(` ${message}`, () => {
beforeEach(mockPlatformIOS);
tests();
afterAll(() => {
unmockProperty(Platform, 'OS');
unmockProperty(PlatformExpo, 'OS');
});
});
describe(`🤖 ${message}`, () => {
beforeEach(mockPlatformAndroid);
tests();
afterAll(() => {
unmockProperty(Platform, 'OS');
unmockProperty(PlatformExpo, 'OS');
});
});
}
export function mockLinking() {
let emitter = new EventEmitter();
let subscriptions = {};
mockProperty(
Linking,
'addEventListener',
jest.fn((type, cb) => {
let subscription = emitter.addListener(type, cb);
subscriptions[type] = subscriptions[type] || new Map();
subscriptions[type].set(cb, subscription);
})
);
mockProperty(
Linking,
'removeEventListener',
jest.fn((type, cb) => {
subscriptions[type].delete(cb);
})
);
return (type, data) => {
emitter.emit(type, data);
};
}