Skip to content

Commit

Permalink
fix(battery): unify tests and fix callback reuse (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
byCedric authored Jan 18, 2020
1 parent 0c4f42a commit 0721bc4
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 93 deletions.
10 changes: 5 additions & 5 deletions packages/battery/src/use-battery-level.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { getBatteryLevelAsync, addBatteryLevelListener } from 'expo-battery';

/**
Expand All @@ -21,9 +21,9 @@ export function useBatteryLevel(
listen = true,
} = options;

function getBatteryLevel() {
return getBatteryLevelAsync().then(setData);
}
const getBatteryLevel = useCallback(() => (
getBatteryLevelAsync().then(setData)
), []);

useEffect(() => {
if (get) {
Expand All @@ -33,7 +33,7 @@ export function useBatteryLevel(
if (listen) {
return addBatteryLevelListener(state => setData(state.batteryLevel)).remove;
}
}, [get, listen]);
}, [get, getBatteryLevel, listen]);

return [data, getBatteryLevel];
}
Expand Down
10 changes: 5 additions & 5 deletions packages/battery/src/use-battery-low-power-mode.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { isLowPowerModeEnabledAsync, addLowPowerModeListener } from 'expo-battery';

/**
Expand All @@ -22,9 +22,9 @@ export function useBatteryLowPowerMode(
listen = true,
} = options;

function getBatteryLowPowerMode() {
return isLowPowerModeEnabledAsync().then(setData);
}
const getBatteryLowPowerMode = useCallback(() => (
isLowPowerModeEnabledAsync().then(setData)
), []);

useEffect(() => {
if (get) {
Expand All @@ -34,7 +34,7 @@ export function useBatteryLowPowerMode(
if (listen) {
return addLowPowerModeListener(state => setData(state.lowPowerMode)).remove;
}
}, [get, listen]);
}, [get, getBatteryLowPowerMode, listen]);

return [data, getBatteryLowPowerMode];
}
Expand Down
10 changes: 5 additions & 5 deletions packages/battery/src/use-battery-state.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { BatteryState, getBatteryStateAsync, addBatteryStateListener } from 'expo-battery';

/**
Expand All @@ -24,9 +24,9 @@ export function useBatteryState(
listen = true,
} = options;

function getBatteryState() {
return getBatteryStateAsync().then(setData);
}
const getBatteryState = useCallback(() => (
getBatteryStateAsync().then(setData)
), []);

useEffect(() => {
if (get) {
Expand All @@ -36,7 +36,7 @@ export function useBatteryState(
if (listen) {
return addBatteryStateListener(state => setData(state.batteryState)).remove;
}
}, [get, listen]);
}, [get, getBatteryState, listen]);

return [data, getBatteryState];
}
Expand Down
10 changes: 5 additions & 5 deletions packages/battery/src/use-battery.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { useEffect, useState, useCallback } from 'react';
import { PowerState, getPowerStateAsync } from 'expo-battery';

/**
Expand All @@ -21,15 +21,15 @@ export function useBattery(
const [data, setData] = useState<PowerState>();
const { get = true } = options;

function getBatteryPowerState() {
return getPowerStateAsync().then(setData);
}
const getBatteryPowerState = useCallback(() => (
getPowerStateAsync().then(setData)
), []);

useEffect(() => {
if (get) {
getBatteryPowerState();
}
}, [get]);
}, [get, getBatteryPowerState]);

return [data, getBatteryPowerState];
}
Expand Down
56 changes: 35 additions & 21 deletions packages/battery/tests/use-battery-level.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,40 @@ it('returns data and get callback when mounted', () => {
expect(hook.result.current[GET]).toBeInstanceOf(Function);
});

it('updates data with get callback', async () => {
jest.spyOn(Battery, 'getBatteryLevelAsync').mockResolvedValue(1);
describe('get callback', () => {
it('updates data with get callback', async () => {
jest.spyOn(Battery, 'getBatteryLevelAsync')
.mockResolvedValue(1);

const hook = renderHook(() => useBatteryLevel({ get: false, listen: false }));
await act(() => hook.result.current[GET]());
const hook = renderHook(() => useBatteryLevel({ get: false, listen: false }));
await act(() => hook.result.current[GET]());

expect(hook.result.current[DATA]).toBe(1);
});

it('uses the same get callback when rerendered', async () => {
const hook = renderHook(() => useBatteryLevel({ get: false, listen: false }));
const getter = hook.result.current[GET];
hook.rerender({ get: false, listen: false });

expect(hook.result.current[DATA]).toBe(1);
expect(getter).toBe(hook.result.current[GET]);
});
});

describe('default behavior', () => {
describe('get option', () => {
it('gets battery level when mounted', async () => {
jest.spyOn(Battery, 'getBatteryLevelAsync').mockResolvedValue(0.1337);
jest.spyOn(Battery, 'getBatteryLevelAsync')
.mockResolvedValue(0.1337);

const hook = renderHook(() => useBatteryLevel({ listen: false }));
await hook.waitForNextUpdate();

expect(hook.result.current[DATA]).toBe(0.1337);
expect(Battery.getBatteryLevelAsync).toBeCalled();
});

it('listens to battery level when mounted', async () => {
const subscription = { remove: jest.fn() };
const listener = jest.spyOn(Battery, 'addBatteryLevelListener').mockReturnValue(subscription);

const hook = renderHook(() => useBatteryLevel({ get: false }));
const handler = listener.mock.calls[0][0];
act(() => handler({ batteryLevel: 0.75 }));

expect(hook.result.current[DATA]).toBe(0.75);
expect(Battery.addBatteryLevelListener).toBeCalled();
});
});

describe('event listener', () => {
describe('listen option', () => {
it('subscribes when mounted', () => {
const listener = jest.spyOn(Battery, 'addBatteryLevelListener');

Expand All @@ -56,11 +56,25 @@ describe('event listener', () => {

it('unsubscribes when unmounted', () => {
const subscription = { remove: jest.fn() };
jest.spyOn(Battery, 'addBatteryLevelListener').mockReturnValue(subscription);
jest.spyOn(Battery, 'addBatteryLevelListener')
.mockReturnValue(subscription);

const hook = renderHook(() => useBatteryLevel({ get: false, listen: true }));
hook.unmount();

expect(subscription.remove).toBeCalled();
});

it('updates the battery level state when mounted', async () => {
const subscription = { remove: jest.fn() };
const listener = jest.spyOn(Battery, 'addBatteryLevelListener')
.mockReturnValue(subscription);

const hook = renderHook(() => useBatteryLevel({ get: false }));
const handler = listener.mock.calls[0][0];
act(() => handler({ batteryLevel: 0.75 }));

expect(hook.result.current[DATA]).toBe(0.75);
expect(Battery.addBatteryLevelListener).toBeCalled();
});
});
56 changes: 35 additions & 21 deletions packages/battery/tests/use-battery-low-power-mode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,40 @@ it('returns data and get callback when mounted', () => {
expect(hook.result.current[GET]).toBeInstanceOf(Function);
});

it('updates data with get callback', async () => {
jest.spyOn(Battery, 'isLowPowerModeEnabledAsync').mockResolvedValue(true);
describe('get callback', () => {
it('updates data with get callback', async () => {
jest.spyOn(Battery, 'isLowPowerModeEnabledAsync')
.mockResolvedValue(true);

const hook = renderHook(() => useBatteryLowPowerMode({ get: false, listen: false }));
await act(() => hook.result.current[GET]());
const hook = renderHook(() => useBatteryLowPowerMode({ get: false, listen: false }));
await act(() => hook.result.current[GET]());

expect(hook.result.current[DATA]).toBe(true);
});

expect(hook.result.current[DATA]).toBe(true);
it('uses the same get callback when rerendered', async () => {
const hook = renderHook(() => useBatteryLowPowerMode({ get: false, listen: false }));
const getter = hook.result.current[GET];
hook.rerender({ get: false, listen: false });

expect(getter).toBe(hook.result.current[GET]);
});
});

describe('default behavior', () => {
describe('get option', () => {
it('gets battery low power mode when mounted', async () => {
jest.spyOn(Battery, 'isLowPowerModeEnabledAsync').mockResolvedValueOnce(true);
jest.spyOn(Battery, 'isLowPowerModeEnabledAsync')
.mockResolvedValueOnce(true);

const hook = renderHook(() => useBatteryLowPowerMode({ listen: false }));
await hook.waitForNextUpdate();

expect(hook.result.current[DATA]).toBe(true);
expect(Battery.isLowPowerModeEnabledAsync).toBeCalled();
});

it('listens to battery low power mode when mounted', async () => {
const subscription = { remove: jest.fn() };
const listener = jest.spyOn(Battery, 'addLowPowerModeListener').mockReturnValue(subscription);

const hook = renderHook(() => useBatteryLowPowerMode({ get: false }));
const handler = listener.mock.calls[0][0];
act(() => handler({ lowPowerMode: false }));

expect(hook.result.current[DATA]).toBe(false);
expect(Battery.addLowPowerModeListener).toBeCalled();
});
});

describe('event listener', () => {
describe('listen option', () => {
it('subscribes when mounted', () => {
const listener = jest.spyOn(Battery, 'addLowPowerModeListener');

Expand All @@ -55,11 +55,25 @@ describe('event listener', () => {

it('unsubscribes when unmounted', () => {
const subscription = { remove: jest.fn() };
jest.spyOn(Battery, 'addLowPowerModeListener').mockReturnValue(subscription);
jest.spyOn(Battery, 'addLowPowerModeListener')
.mockReturnValue(subscription);

const hook = renderHook(() => useBatteryLowPowerMode({ get: false, listen: true }));
hook.unmount();

expect(subscription.remove).toBeCalled();
});

it('listens to battery low power mode when mounted', async () => {
const subscription = { remove: jest.fn() };
const listener = jest.spyOn(Battery, 'addLowPowerModeListener')
.mockReturnValue(subscription);

const hook = renderHook(() => useBatteryLowPowerMode({ get: false }));
const handler = listener.mock.calls[0][0];
act(() => handler({ lowPowerMode: false }));

expect(hook.result.current[DATA]).toBe(false);
expect(Battery.addLowPowerModeListener).toBeCalled();
});
});
58 changes: 36 additions & 22 deletions packages/battery/tests/use-battery-state.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,40 @@ it('returns data and get callback when mounted', () => {
expect(hook.result.current[GET]).toBeInstanceOf(Function);
});

it('updates data with get callback', async () => {
jest.spyOn(Battery, 'getBatteryStateAsync').mockResolvedValue(Battery.BatteryState.FULL);
describe('get callback', () => {
it('updates data with get callback', async () => {
jest.spyOn(Battery, 'getBatteryStateAsync')
.mockResolvedValue(Battery.BatteryState.FULL);

const hook = renderHook(() => useBatteryState({ get: false, listen: false }));
await act(() => hook.result.current[GET]());
const hook = renderHook(() => useBatteryState({ get: false, listen: false }));
await act(() => hook.result.current[GET]());

expect(hook.result.current[DATA]).toBe(Battery.BatteryState.FULL);
});

it('uses the same get callback when rerendered', async () => {
const hook = renderHook(() => useBatteryState({ get: false, listen: false }));
const getter = hook.result.current[GET];
hook.rerender({ get: false, listen: false });

expect(hook.result.current[DATA]).toBe(Battery.BatteryState.FULL);
expect(getter).toBe(hook.result.current[GET]);
});
});

describe('default behavior', () => {
describe('get option', () => {
it('gets battery state when mounted', async () => {
jest.spyOn(Battery, 'getBatteryStateAsync').mockResolvedValue(Battery.BatteryState.UNPLUGGED);
jest.spyOn(Battery, 'getBatteryStateAsync')
.mockResolvedValue(Battery.BatteryState.UNPLUGGED);

const hook = renderHook(() => useBatteryState({ listen: false }));
await hook.waitForNextUpdate();

expect(hook.result.current[DATA]).toBe(Battery.BatteryState.UNPLUGGED);
expect(Battery.getBatteryStateAsync).toBeCalled();
});
})

it('listens to battery state when mounted', async () => {
const subscription = { remove: jest.fn() };
const listener = jest.spyOn(Battery, 'addBatteryStateListener').mockReturnValue(subscription);

const hook = renderHook(() => useBatteryState({ get: false }));
const handler = listener.mock.calls[0][0];
act(() => handler({ batteryState: Battery.BatteryState.UNKNOWN }));

expect(hook.result.current[DATA]).toBe(Battery.BatteryState.UNKNOWN);
expect(Battery.addBatteryStateListener).toBeCalled();
});
});

describe('event listener', () => {
describe('listen option', () => {
it('subscribes when mounted', () => {
const listener = jest.spyOn(Battery, 'addBatteryStateListener');

Expand All @@ -55,11 +55,25 @@ describe('event listener', () => {

it('unsubscribes when unmounted', () => {
const subscription = { remove: jest.fn() };
jest.spyOn(Battery, 'addBatteryStateListener').mockReturnValue(subscription);
jest.spyOn(Battery, 'addBatteryStateListener')
.mockReturnValue(subscription);

const hook = renderHook(() => useBatteryState({ get: false, listen: true }));
hook.unmount();

expect(subscription.remove).toBeCalled();
});

it('updates the battery state when mounted', async () => {
const subscription = { remove: jest.fn() };
const listener = jest.spyOn(Battery, 'addBatteryStateListener')
.mockReturnValue(subscription);

const hook = renderHook(() => useBatteryState({ get: false, listen: true }));
const handler = listener.mock.calls[0][0];
act(() => handler({ batteryState: Battery.BatteryState.UNKNOWN }));

expect(hook.result.current[DATA]).toBe(Battery.BatteryState.UNKNOWN);
expect(Battery.addBatteryStateListener).toBeCalled();
});
});
Loading

0 comments on commit 0721bc4

Please sign in to comment.