Improve code coverage

This commit is contained in:
David Lechner
2022-02-22 12:32:20 -06:00
parent b3ed75f02b
commit a0da9f7111
6 changed files with 153 additions and 1 deletions
+27
View File
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2021 The Pybricks Authors
import { I18nContext, I18nManager } from '@shopify/react-i18n';
import { render } from '@testing-library/react';
import { mock } from 'jest-mock-extended';
import React from 'react';
import { Provider } from 'react-redux';
import { Store } from 'redux';
import { RootState } from '../reducers';
import App from './App';
it.each([false, true])('should render', (darkMode) => {
const store = mock<Store<RootState>>({
getState: () => mock<RootState>({ settings: { darkMode } }),
});
const i18n = new I18nManager({ locale: 'en' });
render(
<Provider store={store}>
<I18nContext.Provider value={i18n}>
<App />
</I18nContext.Provider>
</Provider>,
);
});
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2021 The Pybricks Authors
import {
HubType,
LegoCompanyId,
TechnicLargeHubVariant,
} from '../ble-lwp3-service/protocol';
import { decodePnpId, getHubTypeName } from './protocol';
function encodeInfo(id: HubType, variant?: number) {
return new DataView(
new Uint8Array([
1, // Bluetooth SIG
LegoCompanyId & 0xff,
LegoCompanyId >> 8,
id,
0,
variant ?? 0,
0,
]).buffer,
);
}
test.each([
[encodeInfo(HubType.MoveHub), 'Move hub'],
[encodeInfo(HubType.CityHub), 'City hub'],
[encodeInfo(HubType.TechnicHub), 'Technic hub'],
[
encodeInfo(HubType.TechnicLargeHub, TechnicLargeHubVariant.SpikePrimeHub),
'Prime hub',
],
[
encodeInfo(
HubType.TechnicLargeHub,
TechnicLargeHubVariant.MindstormsInventorHub,
),
'Inventor hub',
],
[encodeInfo(HubType.TechnicSmallHub), 'Essential hub'],
])('should correctly decode data', (data, expected) => {
expect(getHubTypeName(decodePnpId(data))).toBe(expected);
});
+69 -1
View File
@@ -1,11 +1,15 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2021 The Pybricks Authors
import { fireEvent, render, screen } from '@testing-library/react';
import { I18nContext, I18nManager } from '@shopify/react-i18n';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { mock } from 'jest-mock-extended';
import React from 'react';
import { Provider } from 'react-redux';
import { Store } from 'redux';
import { BleConnectionState } from '../ble/reducers';
import { RootState } from '../reducers';
import StatusBar from './StatusBar';
it('should prevent browser context menu', () => {
@@ -24,3 +28,67 @@ it('should prevent browser context menu', () => {
expect(fireEvent.contextMenu(screen.getByRole('status'))).toBe(false);
});
it('should show popover when hub name is clicked', async () => {
const testHubName = 'Test hub';
const store = mock<Store<RootState>>({
getState: () =>
mock<RootState>({
ble: {
connection: BleConnectionState.Connected,
deviceName: testHubName,
deviceType: 'hub type',
deviceFirmwareVersion: 'v0.0.0',
deviceLowBatteryWarning: false,
deviceBatteryCharging: false,
},
}),
});
const i18n = new I18nManager({ locale: 'en' });
render(
<Provider store={store}>
<I18nContext.Provider value={i18n}>
<StatusBar />
</I18nContext.Provider>
</Provider>,
);
userEvent.click(screen.getByText(testHubName));
await waitFor(() => screen.getByText('Connected to:'));
});
it('should show popover when battery is clicked', async () => {
const testHubName = 'Test hub';
const store = mock<Store<RootState>>({
getState: () =>
mock<RootState>({
ble: {
connection: BleConnectionState.Connected,
deviceName: testHubName,
deviceType: 'hub type',
deviceFirmwareVersion: 'v0.0.0',
deviceLowBatteryWarning: false,
deviceBatteryCharging: false,
},
}),
});
const i18n = new I18nManager({ locale: 'en' });
render(
<Provider store={store}>
<I18nContext.Provider value={i18n}>
<StatusBar />
</I18nContext.Provider>
</Provider>,
);
userEvent.click(screen.getByTitle('Battery'));
await waitFor(() => screen.getByText('Battery level is OK.'));
});
+1
View File
@@ -106,6 +106,7 @@ const Terminal: React.FC = (_props) => {
// xterm.open() has to be called after terminalRef has been rendered
useEffect(() => {
// istanbul ignore if: should not happen ever
if (!terminalRef.current) {
console.error('Missing terminal reference');
return;
+11
View File
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2021 The Pybricks Authors
import { render } from '@testing-library/react';
import React from 'react';
import ViewHeightSensor from './ViewHeightSensor';
it('should set the --pb-vh variable on resize', () => {
render(<ViewHeightSensor />);
// REVISIT: it is not easy to test the resize event since jest-dom doesn't do layout
});
+2
View File
@@ -26,6 +26,7 @@ export function useTooltip2MonkeyPatch<T>(): React.RefObject<Tooltip2<T>> {
const tooltipRef = useRef<Tooltip2<T>>(null);
useEffect(() => {
// istanbul ignore if: should not happen ever
if (!tooltipRef.current) {
return;
}
@@ -55,6 +56,7 @@ export function useTooltip2MonkeyPatch<T>(): React.RefObject<Tooltip2<T>> {
* @param tooltipRef The reference returned from useTooltip2MonkeyPatch()
*/
export function closeTooltip2<T>(tooltipRef: React.RefObject<Tooltip2<T>>): void {
// istanbul ignore if: should not happen ever
if (!tooltipRef.current) {
return;
}