- App.tsx: full navigation (Auth stack + Main tabs with 5 screens) - Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen - HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors - MapScreen: interactive map with layer toggles (6 layers) - MarketplaceScreen: categories (6), products (5), search - ChatScreen: AI chat with quick prompts (4), bot responses - ProfileScreen: user info, stats, menu (9 items), logout - AlertsScreen: alert list with severity, acknowledge - SensorsScreen: sensor list with type filters (6 types), search - ZonesScreen: zone cards with stats - SettingsScreen: language picker (FR/EN/ES/DE), privacy, about - Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n - Hooks: useSensors, useAlerts, useNotifications, useLocation - Components: Card, Button, LoadingSpinner, ErrorBoundary, Header - Services: iotService, notificationService (with axios API client) - Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN) - Theme: colors.ts with full design system (Blue Ocean palette) - Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
174 lines
5.3 KiB
JavaScript
174 lines
5.3 KiB
JavaScript
/* eslint-disable @typescript-eslint/no-namespace */
|
|
'use strict';
|
|
|
|
import { isJest } from './PlatformChecker';
|
|
const defaultFramerateConfig = {
|
|
fps: 60
|
|
};
|
|
const getCurrentStyle = component => {
|
|
const styleObject = component.props.style;
|
|
let currentStyle = {};
|
|
if (Array.isArray(styleObject)) {
|
|
styleObject.forEach(style => {
|
|
currentStyle = {
|
|
...currentStyle,
|
|
...style
|
|
};
|
|
});
|
|
} else {
|
|
var _component$props$jest;
|
|
currentStyle = {
|
|
...styleObject,
|
|
...((_component$props$jest = component.props.jestAnimatedStyle) === null || _component$props$jest === void 0 ? void 0 : _component$props$jest.value)
|
|
};
|
|
}
|
|
return currentStyle;
|
|
};
|
|
const checkEqual = (current, expected) => {
|
|
if (Array.isArray(expected)) {
|
|
if (!Array.isArray(current) || expected.length !== current.length) {
|
|
return false;
|
|
}
|
|
for (let i = 0; i < current.length; i++) {
|
|
if (!checkEqual(current[i], expected[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
} else if (typeof current === 'object' && current) {
|
|
if (typeof expected !== 'object' || !expected) {
|
|
return false;
|
|
}
|
|
for (const property in expected) {
|
|
if (!checkEqual(current[property], expected[property])) {
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
return current === expected;
|
|
}
|
|
return true;
|
|
};
|
|
const findStyleDiff = (current, expected, shouldMatchAllProps) => {
|
|
const diffs = [];
|
|
let isEqual = true;
|
|
let property;
|
|
for (property in expected) {
|
|
if (!checkEqual(current[property], expected[property])) {
|
|
isEqual = false;
|
|
diffs.push({
|
|
property,
|
|
current: current[property],
|
|
expect: expected[property]
|
|
});
|
|
}
|
|
}
|
|
if (shouldMatchAllProps && Object.keys(current).length !== Object.keys(expected).length) {
|
|
isEqual = false;
|
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
let property;
|
|
for (property in current) {
|
|
if (expected[property] === undefined) {
|
|
diffs.push({
|
|
property,
|
|
current: current[property],
|
|
expect: expected[property]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
isEqual,
|
|
diffs
|
|
};
|
|
};
|
|
const compareStyle = (component, expectedStyle, config) => {
|
|
if (!component.props.style) {
|
|
return {
|
|
message: () => `Component doesn't have a style.`,
|
|
pass: false
|
|
};
|
|
}
|
|
const {
|
|
shouldMatchAllProps
|
|
} = config;
|
|
const currentStyle = getCurrentStyle(component);
|
|
const {
|
|
isEqual,
|
|
diffs
|
|
} = findStyleDiff(currentStyle, expectedStyle, shouldMatchAllProps);
|
|
if (isEqual) {
|
|
return {
|
|
message: () => 'ok',
|
|
pass: true
|
|
};
|
|
}
|
|
const currentStyleStr = JSON.stringify(currentStyle);
|
|
const expectedStyleStr = JSON.stringify(expectedStyle);
|
|
const differences = diffs.map(diff => `- '${diff.property}' should be ${JSON.stringify(diff.expect)}, but is ${JSON.stringify(diff.current)}`).join('\n');
|
|
return {
|
|
message: () => `Expected: ${expectedStyleStr}\nReceived: ${currentStyleStr}\n\nDifferences:\n${differences}`,
|
|
pass: false
|
|
};
|
|
};
|
|
let frameTime = Math.round(1000 / defaultFramerateConfig.fps);
|
|
const beforeTest = () => {
|
|
jest.useFakeTimers();
|
|
};
|
|
const afterTest = () => {
|
|
jest.runOnlyPendingTimers();
|
|
jest.useRealTimers();
|
|
};
|
|
export const withReanimatedTimer = animationTest => {
|
|
console.warn('This method is deprecated, you should define your own before and after test hooks to enable jest.useFakeTimers(). Check out the documentation for details on testing');
|
|
beforeTest();
|
|
animationTest();
|
|
afterTest();
|
|
};
|
|
export const advanceAnimationByTime = (time = frameTime) => {
|
|
console.warn('This method is deprecated, use jest.advanceTimersByTime directly');
|
|
jest.advanceTimersByTime(time);
|
|
jest.runOnlyPendingTimers();
|
|
};
|
|
export const advanceAnimationByFrame = count => {
|
|
console.warn('This method is deprecated, use jest.advanceTimersByTime directly');
|
|
jest.advanceTimersByTime(count * frameTime);
|
|
jest.runOnlyPendingTimers();
|
|
};
|
|
const requireFunction = isJest() ? require : () => {
|
|
throw new Error('[Reanimated] `setUpTests` is available only in Jest environment.');
|
|
};
|
|
export const setUpTests = (userFramerateConfig = {}) => {
|
|
let expect = global.expect;
|
|
if (expect === undefined) {
|
|
const expectModule = requireFunction('expect');
|
|
expect = expectModule;
|
|
// Starting from Jest 28, "expect" package uses named exports instead of default export.
|
|
// So, requiring "expect" package doesn't give direct access to "expect" function anymore.
|
|
// It gives access to the module object instead.
|
|
// We use this info to detect if the project uses Jest 28 or higher.
|
|
if (typeof expect === 'object') {
|
|
const jestGlobals = requireFunction('@jest/globals');
|
|
expect = jestGlobals.expect;
|
|
}
|
|
if (expect === undefined || expect.extend === undefined) {
|
|
expect = expectModule.default;
|
|
}
|
|
}
|
|
const framerateConfig = {
|
|
...defaultFramerateConfig,
|
|
...userFramerateConfig
|
|
};
|
|
frameTime = Math.round(1000 / framerateConfig.fps);
|
|
expect.extend({
|
|
toHaveAnimatedStyle(component, expectedStyle, config = {}) {
|
|
return compareStyle(component, expectedStyle, config);
|
|
}
|
|
});
|
|
};
|
|
export const getAnimatedStyle = component => {
|
|
return getCurrentStyle(
|
|
// This type assertion is needed to get type checking in the following
|
|
// functions since `ReactTestInstance` has its `props` defined as `any`.
|
|
component);
|
|
};
|
|
//# sourceMappingURL=jestUtils.js.map
|