@applicaster/zapp-react-native-utils 12.0.0-alpha.4081044014 → 12.0.0-alpha.4102526423

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -85,7 +85,18 @@ export class AccessibilityManager {
85
85
  textToRead = localizedMessage;
86
86
  }
87
87
 
88
- this.ttsManager && this.ttsManager.readText(textToRead);
88
+ if (this.ttsManager) {
89
+ logger.debug({
90
+ message: `Reading text: ${textToRead}`,
91
+ data: {
92
+ textToRead,
93
+ text,
94
+ keyOfLocalizedText,
95
+ },
96
+ });
97
+
98
+ this.ttsManager.readText(textToRead);
99
+ }
89
100
 
90
101
  this.announcements$.next({
91
102
  message: textToRead,
@@ -50,7 +50,7 @@ export const usePlayerControllerSetup = ({
50
50
  });
51
51
 
52
52
  setPlayerController(newPlayerController);
53
- }, [playerId, entry?.id]);
53
+ }, [playerId, entry?.id, ref.current]);
54
54
 
55
55
  React.useEffect(() => {
56
56
  if (!playerController) {
@@ -58,7 +58,7 @@ export const usePlayerControllerSetup = ({
58
58
  }
59
59
 
60
60
  if (!playerManager) {
61
- return;
61
+ return null;
62
62
  }
63
63
 
64
64
  if (playerManager.isPlayerRegistered(playerId)) {
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable unused-imports/no-unused-vars */
2
2
  import * as R from "ramda";
3
- import { invariant } from "@applicaster/zapp-react-native-utils/errorUtils";
4
3
 
5
4
  /**
6
5
  * shifts an array by the given offset. a negative offset will take items
@@ -101,13 +100,3 @@ export const makeListOf = (value: unknown, size: number): number[] => {
101
100
  export function isFilledArray(value: unknown): boolean {
102
101
  return R.is(Array, value) && R.length(value) > 0;
103
102
  }
104
-
105
- // get random item from the list
106
- export const sample = (xs: unknown[]): unknown => {
107
- invariant(R.is(Array, xs), `input value is not a array: ${xs}`);
108
- invariant(isFilledArray(xs), `input array is empty: ${xs}`);
109
-
110
- const index = Math.floor(Math.random() * xs.length);
111
-
112
- return xs[index];
113
- };
@@ -18,7 +18,6 @@ class FocusManager {
18
18
  private static instance: FocusManager;
19
19
 
20
20
  private _focusedId: string | null = null;
21
- private _prevFocusedId: string | null = null;
22
21
  public previousNavigationDirection: FocusManager.Android.NavDir = null;
23
22
 
24
23
  /**
@@ -48,22 +47,10 @@ class FocusManager {
48
47
  return focusedRef?.current;
49
48
  }
50
49
 
51
- get prevFocused() {
52
- const focusedRef = this.prevFocusedId
53
- ? FocusManager.findFocusable(this.prevFocusedId)
54
- : { current: null };
55
-
56
- return focusedRef?.current;
57
- }
58
-
59
50
  get focusedId() {
60
51
  return FocusManager.instance._focusedId;
61
52
  }
62
53
 
63
- get prevFocusedId() {
64
- return FocusManager.instance._prevFocusedId;
65
- }
66
-
67
54
  public static getInstance(): FocusManager {
68
55
  if (!FocusManager.instance) {
69
56
  FocusManager.instance = new FocusManager();
@@ -164,8 +151,9 @@ class FocusManager {
164
151
  }
165
152
 
166
153
  private setFocusLocal(nextFocus: FocusManager.TouchableReactRef) {
167
- FocusManager.instance._prevFocusedId = FocusManager.instance._focusedId;
168
154
  FocusManager.instance._focusedId = nextFocus?.current?.props?.id ?? null;
155
+
156
+ this.eventHandler?.invokeHandler?.(FOCUS_EVENTS.FOCUS, nextFocus);
169
157
  }
170
158
 
171
159
  private setPreviousNavigationDirection(
@@ -229,11 +217,8 @@ class FocusManager {
229
217
 
230
218
  FocusManager.instance.setFocus(nextNextFocus, options);
231
219
  } else {
232
- FocusManager.instance.setFocusLocal(nextFocus);
233
-
234
220
  FocusManager.instance.blurPrevious(options);
235
- this.eventHandler?.invokeHandler?.(FOCUS_EVENTS.FOCUS, nextFocus);
236
-
221
+ FocusManager.instance.setFocusLocal(nextFocus);
237
222
  FocusManager.instance.setPreviousNavigationDirection(options ?? null);
238
223
 
239
224
  nextFocus?.current?.onFocus?.(nextFocus.current, options ?? {});
@@ -242,8 +227,8 @@ class FocusManager {
242
227
 
243
228
  blurPrevious(options?: FocusManager.Android.CallbackOptions) {
244
229
  if (options) {
245
- FocusManager.instance.prevFocused?.onBlur?.(
246
- FocusManager.instance.prevFocused,
230
+ FocusManager.instance.focused?.onBlur?.(
231
+ FocusManager.instance.focused,
247
232
  options
248
233
  );
249
234
  }
@@ -156,6 +156,7 @@ describe("FocusManager", () => {
156
156
  child1.current.onBlur.mockClear();
157
157
  focusManager.setFocus(child1.current.props.id);
158
158
  focusManager.blurPrevious({ direction: "down" });
159
+ expect(child1.current.onBlur).toBeCalled();
159
160
  });
160
161
 
161
162
  it("focusManager - focus shouldn't change if nextFocus has blockFocus", () => {
@@ -263,7 +263,7 @@ export function getTargetRoute(
263
263
  pathname = "",
264
264
  {
265
265
  contentTypes = undefined,
266
- layoutVersion = "v2",
266
+ layoutVersion = undefined,
267
267
  rivers = {},
268
268
  }: {
269
269
  contentTypes?: ZappContentTypes | null;
@@ -66,23 +66,3 @@ export const isZero = (value: unknown): boolean =>
66
66
  export const isMinusZero = (value: number) => {
67
67
  return 1 / value === -Infinity;
68
68
  };
69
-
70
- export const toPositiveNumberWithDefault = (
71
- defaultValue: number,
72
- value: unknown
73
- ): number => {
74
- const possibleNumber = toNumber(value);
75
-
76
- if (R.isNil(possibleNumber)) {
77
- return defaultValue;
78
- }
79
-
80
- if (possibleNumber < 0) {
81
- return defaultValue;
82
- }
83
-
84
- return possibleNumber;
85
- };
86
-
87
- export const toPositiveNumberWithDefaultZero = (value: unknown): number =>
88
- toPositiveNumberWithDefault(0, value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-utils",
3
- "version": "12.0.0-alpha.4081044014",
3
+ "version": "12.0.0-alpha.4102526423",
4
4
  "description": "Applicaster Zapp React Native utilities package",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "homepage": "https://github.com/applicaster/quickbrick#readme",
30
30
  "dependencies": {
31
- "@applicaster/applicaster-types": "12.0.0-alpha.4081044014",
31
+ "@applicaster/applicaster-types": "12.0.0-alpha.4102526423",
32
32
  "buffer": "^5.2.1",
33
33
  "camelize": "^1.0.0",
34
34
  "create-react-context": "^0.2.3",
@@ -30,15 +30,7 @@ type Props = {
30
30
  zappPipesData?: ZappPipesData;
31
31
  };
32
32
 
33
- type onPressReturnFn =
34
- | ((_item?: ZappEntry | any, _index?: number) => Promise<void>)
35
- | (() => void);
36
-
37
- export const useCellClick = ({
38
- component,
39
- zappPipesData,
40
- item,
41
- }: Props): onPressReturnFn => {
33
+ export const useCellClick = ({ component, zappPipesData, item }: Props) => {
42
34
  const { push, currentRoute } = useNavigation();
43
35
  const { pathname } = useRoute();
44
36
 
@@ -114,15 +106,9 @@ export const useCellClick = ({
114
106
  ]
115
107
  );
116
108
 
117
- const onPressRef = React.useRef<onPressReturnFn>();
118
-
119
109
  if (!cellSelectable) {
120
- // update ref with dummy function
121
- onPressRef.current = noop;
122
- } else {
123
- // update ref with the latest onPress function
124
- onPressRef.current = onPress;
110
+ return noop;
125
111
  }
126
112
 
127
- return React.useCallback(onPressRef.current, []);
113
+ return onPress;
128
114
  };
@@ -77,6 +77,8 @@ describe("useBatchLoading", () => {
77
77
 
78
78
  const actions = store.getActions();
79
79
 
80
+ expect(useDispatchSpy).toBeCalledTimes(1);
81
+
80
82
  expect(actions).toHaveLength(2);
81
83
 
82
84
  expect(actions[0]).toMatchObject({
@@ -127,8 +129,6 @@ describe("useBatchLoading", () => {
127
129
  // ... more items
128
130
  ];
129
131
 
130
- expect(useDispatchSpy).toBeCalledTimes(0);
131
-
132
132
  renderHook(() => useBatchLoading(data, { initialBatchSize, riverId }), {
133
133
  wrapper,
134
134
  initialProps: { store },
@@ -136,6 +136,8 @@ describe("useBatchLoading", () => {
136
136
 
137
137
  const actions = store.getActions();
138
138
 
139
+ expect(useDispatchSpy).toBeCalledTimes(1);
140
+
139
141
  expect(actions).toHaveLength(1);
140
142
 
141
143
  expect(actions[0]).toMatchObject({
@@ -170,6 +172,8 @@ describe("useBatchLoading", () => {
170
172
  initialProps: { store },
171
173
  });
172
174
 
175
+ expect(useDispatchSpy).toBeCalledTimes(1);
176
+
173
177
  const actions = store.getActions();
174
178
 
175
179
  expect(actions).toHaveLength(3);
@@ -214,73 +218,6 @@ describe("useBatchLoading", () => {
214
218
 
215
219
  expect(result.current).toBe(true);
216
220
  });
217
-
218
- it("gallery-qb: loadPipesData should be called only once for first component in the gallery", () => {
219
- const store = mockStore({
220
- zappPipes: {},
221
- test: "true",
222
- });
223
-
224
- useDispatchSpy.mockReturnValue(store.dispatch);
225
-
226
- const initialBatchSize = 3;
227
- const riverId = "123";
228
-
229
- const data = [
230
- {
231
- component_type: "gallery-qb",
232
- ui_components: [{ data: { source: "url1" } }],
233
- },
234
- { data: { source: "url2" } },
235
- { data: { source: "url3" } },
236
- { data: { source: "url4" } },
237
- { data: { source: "url5" } },
238
- { data: { source: "url6" } },
239
- // ... more items
240
- ];
241
-
242
- renderHook(() => useBatchLoading(data, { initialBatchSize, riverId }), {
243
- wrapper,
244
- initialProps: { store },
245
- });
246
-
247
- const actions = store.getActions();
248
-
249
- expect(actions).toHaveLength(1);
250
- });
251
-
252
- it("gallery-qb: initial batch ready when all initial items loaded", () => {
253
- const store = mockStore({
254
- zappPipes: {
255
- url1: {
256
- loading: false,
257
- error: false,
258
- data: {},
259
- },
260
- },
261
- });
262
-
263
- useDispatchSpy.mockReturnValue(store.dispatch);
264
-
265
- const initialBatchSize = 3;
266
- const riverId = "123";
267
-
268
- const data: Partial<ZappUIComponent>[] = [
269
- {
270
- component_type: "gallery-qb",
271
- ui_components: [{ data: { source: "url1" } }],
272
- },
273
- { data: { source: "url2" } },
274
- { data: { source: "url3" } },
275
- ];
276
-
277
- const { result } = renderHook(
278
- () => useBatchLoading(data, { initialBatchSize, riverId }),
279
- { wrapper, initialProps: { store } }
280
- );
281
-
282
- expect(result.current).toBe(true);
283
- });
284
221
  });
285
222
 
286
223
  describe("allFeedsIsReady", () => {
@@ -45,23 +45,19 @@ const filterEmptyData = (data) => {
45
45
  return true;
46
46
  };
47
47
 
48
- const getData = (rawData) =>
49
- rawData.component_type === "gallery-qb"
50
- ? rawData.ui_components[0].data
51
- : rawData.data;
52
-
53
- const extractData = compose(uniq, map(getData));
48
+ const extractData = compose(uniq, map(dataOf));
54
49
 
55
50
  export const allFeedsIsReady = (
56
51
  feeds: ZappPipesCollection,
57
52
  urls: (ZappDataSourceSource | null)[]
58
53
  ): boolean =>
59
- urls.every((url) =>
60
- isNil(url) ? true : url && feeds[url] ? checkFeedIsReady(feeds[url]) : false
61
- );
54
+ urls
55
+ .filter(complement(isNil))
56
+ .map((url) => (url ? checkFeedIsReady(feeds[url]) : false))
57
+ .every(Boolean);
62
58
 
63
59
  export const useBatchLoading = (
64
- componentsToRender: { data?: ZappDataSource; component_type: string }[],
60
+ data: { data?: ZappDataSource }[],
65
61
  options: Options
66
62
  ) => {
67
63
  const dispatch = useDispatch();
@@ -69,18 +65,10 @@ export const useBatchLoading = (
69
65
  const [searchContext] = ZappPipesSearchContext.useZappPipesContext();
70
66
  const [hasEverBeenReady, setHasEverBeenReady] = React.useState(false);
71
67
 
72
- // if first component is gallery-qb, take only one component for initial load
73
- const takeSize =
74
- componentsToRender?.[0]?.component_type === "gallery-qb"
75
- ? 1
76
- : min(
77
- options.initialBatchSize ?? DEFAULT_BATCH_SIZE,
78
- componentsToRender.length
79
- );
80
-
81
- const takeBatchSize = React.useCallback(take(takeSize), [takeSize]);
68
+ const takeBatchSize = take(
69
+ min(options.initialBatchSize ?? DEFAULT_BATCH_SIZE, data.length)
70
+ );
82
71
 
83
- // Prepare inflated url for datasource
84
72
  const getUrl = React.useCallback(
85
73
  (data) => {
86
74
  const mappedFeed = data.mapping
@@ -100,16 +88,13 @@ export const useBatchLoading = (
100
88
  [entryContext, screenContext, searchContext]
101
89
  );
102
90
 
103
- // components for initial load
104
- const batchComponents = takeBatchSize(componentsToRender);
91
+ const batchData = takeBatchSize(data);
105
92
 
106
- // contains datasources from batch components loading
107
93
  const feedData: ZappDataSource[] = React.useMemo(
108
- () => extractData(batchComponents).filter(filterEmptyData),
109
- [batchComponents]
94
+ () => extractData(batchData).filter(filterEmptyData),
95
+ [batchData]
110
96
  );
111
97
 
112
- // contains inflated urls from batch components loading
113
98
  const feedUrls: ZappDataSourceSource[] = React.useMemo(
114
99
  () =>
115
100
  feedData.map((data) => {
@@ -117,43 +102,34 @@ export const useBatchLoading = (
117
102
 
118
103
  return mappedFeedUrl;
119
104
  }),
120
- []
105
+ [] // No watchers as batch loaders is used only for initial load
121
106
  );
122
107
 
123
108
  const feeds = useZappPipesFeeds(feedUrls);
124
109
 
125
- // dispatch loadPipesData for each feed that is not loaded
126
- const runBatchLoading = React.useCallback(() => {
127
- batchComponents.forEach((rawData: any) => {
128
- // 1. get data (dataOf)
129
-
130
- const data = getData(rawData);
110
+ React.useEffect(() => {
111
+ const datasources = map(dataOf, batchData)
112
+ .filter(filterEmptyData)
113
+ .filter((data) => {
114
+ const feed = feeds[data.source];
131
115
 
132
- // 2. filter out empty data filterEmptyData
133
- if (!filterEmptyData(data)) return false;
116
+ if (!feed) return true;
134
117
 
135
- // 3. filter out data that is already loaded (feeds[data.source]) & !feedHasData(feed) && !feedIsLoading(feed);
136
- const feed = feeds[data?.source];
118
+ return !feedHasData(feed) && !feedIsLoading(feed);
119
+ });
137
120
 
138
- if (!feed || (!feedHasData(feed) && !feedIsLoading(feed))) {
139
- const mappedFeedUrl = getUrl(data);
121
+ datasources.forEach((data) => {
122
+ const mappedFeedUrl = getUrl(data);
140
123
 
141
- if (mappedFeedUrl) {
142
- // 4. load data
143
- return dispatch(
144
- loadPipesData(mappedFeedUrl, { riverId: options.riverId })
145
- );
146
- }
124
+ if (mappedFeedUrl) {
125
+ return dispatch(
126
+ loadPipesData(mappedFeedUrl, { riverId: options.riverId })
127
+ );
147
128
  }
148
129
  });
149
- }, [feedUrls]);
150
-
151
- React.useEffect(() => {
152
- runBatchLoading();
153
- }, []);
130
+ }, []); // No watchers as batch loaders is used only for initial load
154
131
 
155
132
  React.useEffect(() => {
156
- // check if all feeds are ready and set hasEverBeenReady to true
157
133
  if (allFeedsIsReady(feeds, feedUrls) && !hasEverBeenReady) {
158
134
  setHasEverBeenReady(true);
159
135
  }
@@ -17,7 +17,7 @@ import {
17
17
  QUICK_BRICK_NAVBAR,
18
18
  QUICK_BRICK_CONTENT,
19
19
  } from "@applicaster/quick-brick-core/const";
20
- import { useZappHooksModalState } from "@applicaster/zapp-react-dom-ui-components/Components/ZappHooksModal/hooks/useZappHooksModalState";
20
+ import { useZappHooksModalState } from "@applicaster/zapp-react-dom-ui-components/Components/ZappHooksModal/ZappHooksModal";
21
21
  import { ZappHookModalContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
22
22
  import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
23
23
  import { HookModalContextT } from "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext";
@@ -7,11 +7,9 @@ import { Provider } from "react-redux";
7
7
  import thunk from "redux-thunk";
8
8
  import configureStore from "redux-mock-store";
9
9
  import { SafeAreaProvider } from "react-native-safe-area-context";
10
- import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
11
10
 
12
11
  import { render } from "@testing-library/react-native";
13
12
  import { AnalyticsProvider } from "../analyticsUtils";
14
- import { ThemeContext } from "../theme";
15
13
 
16
14
  export { getByTestId } from "./getByTestId";
17
15
 
@@ -61,9 +59,7 @@ const initialState = {
61
59
  appSettings: {},
62
60
  plugins: [],
63
61
  appState: { appReady: true, appLaunched: true },
64
- pluginConfigurations: {},
65
62
  appData: { layoutVersion: "v1" },
66
- zappPipes: {},
67
63
  contentTypes: null,
68
64
  };
69
65
 
@@ -72,49 +68,20 @@ export const WrappedWithProviders = ({
72
68
  store: storeObj = {},
73
69
  }: any) => {
74
70
  const _store = configureStore([thunk])(
75
- R.mergeDeepRight(initialState, { ...storeObj })
71
+ R.mergeDeepWith(R.concat, { ...initialState }, storeObj)
76
72
  );
77
73
 
78
- appStore.set(_store);
79
-
80
74
  return (
81
- <ThemeContext.Provider
82
- value={{
83
- themes: {
84
- light: {
85
- component_margin_top: 0,
86
- component_margin_bottom: 0,
87
- component_margin_left: 0,
88
- component_margin_right: 0,
89
- component_padding_top: 0,
90
- component_padding_bottom: 0,
91
- component_padding_left: 0,
92
- component_padding_right: 0,
93
- component_gutter_vertical: 0,
94
- component_gutter_horizontal: 0,
95
- component_corner_radius: 0,
96
- app_background_color: "rgba(0,0,0,0)",
97
- screen_margin_top: 0,
98
- screen_margin_bottom: 0,
99
- component_anchor_point_y: 0,
100
- assets: "",
101
- },
102
- },
103
- selectedThemeId: "light",
104
- setSelectedThemeId: () => {},
75
+ <SafeAreaProvider
76
+ initialMetrics={{
77
+ insets: { top: 0, left: 0, right: 0, bottom: 0 },
78
+ frame: { x: 0, y: 0, width: 0, height: 0 },
105
79
  }}
106
80
  >
107
- <SafeAreaProvider
108
- initialMetrics={{
109
- insets: { top: 0, left: 0, right: 0, bottom: 0 },
110
- frame: { x: 0, y: 0, width: 0, height: 0 },
111
- }}
112
- >
113
- <Provider store={_store}>
114
- <AnalyticsProvider>{children}</AnalyticsProvider>
115
- </Provider>
116
- </SafeAreaProvider>
117
- </ThemeContext.Provider>
81
+ <Provider store={_store}>
82
+ <AnalyticsProvider>{children}</AnalyticsProvider>
83
+ </Provider>
84
+ </SafeAreaProvider>
118
85
  );
119
86
  };
120
87
 
@@ -1,66 +0,0 @@
1
- import { toPositiveNumberWithDefault } from "..";
2
-
3
- describe("toNumber", () => {
4
- const DEFAULT = 5;
5
-
6
- it("return number if input is positive number", () => {
7
- const inputs = [0, 1, 2, 100, 200.12, Infinity];
8
- expect.assertions(inputs.length);
9
-
10
- inputs.forEach((input) => {
11
- const output = toPositiveNumberWithDefault(DEFAULT, input);
12
- expect(output).toBe(input);
13
- });
14
- });
15
-
16
- it("return number if input is positive number as string", () => {
17
- const inputs = ["0", "1", "2", "100", "200.12"];
18
- expect.assertions(inputs.length);
19
-
20
- inputs.forEach((input) => {
21
- const output = toPositiveNumberWithDefault(DEFAULT, input);
22
- expect(output).toBe(Number(input));
23
- });
24
- });
25
-
26
- it("return default number if input is negative number", () => {
27
- const inputs = [-1, -2, -100, -Infinity];
28
- expect.assertions(inputs.length);
29
-
30
- inputs.forEach((input) => {
31
- const output = toPositiveNumberWithDefault(DEFAULT, input);
32
- expect(output).toBe(DEFAULT);
33
- });
34
- });
35
-
36
- it("return default number if input is negative number as string", () => {
37
- const inputs = ["-1", "-2", "-100"];
38
- expect.assertions(inputs.length);
39
-
40
- inputs.forEach((input) => {
41
- const output = toPositiveNumberWithDefault(DEFAULT, input);
42
- expect(output).toBe(DEFAULT);
43
- });
44
- });
45
-
46
- it("return default if input is not a number or infinite", () => {
47
- const inputs = [
48
- "vfdvf",
49
- null,
50
- undefined,
51
- NaN,
52
- "",
53
- {},
54
- { test: 1 },
55
- [],
56
- [1],
57
- ];
58
-
59
- expect.assertions(inputs.length);
60
-
61
- inputs.forEach((input) => {
62
- const output = toPositiveNumberWithDefault(DEFAULT, input);
63
- expect(output).toBe(DEFAULT);
64
- });
65
- });
66
- });
@@ -1,66 +0,0 @@
1
- import { toPositiveNumberWithDefaultZero } from "..";
2
-
3
- const DEFAULT = 0;
4
-
5
- describe("toNumber", () => {
6
- it("return number if input is positive number", () => {
7
- const inputs = [0, 1, 2, 100, 200.12];
8
- expect.assertions(inputs.length);
9
-
10
- inputs.forEach((input) => {
11
- const output = toPositiveNumberWithDefaultZero(input);
12
- expect(output).toBe(input);
13
- });
14
- });
15
-
16
- it("return number if input is positive number as string", () => {
17
- const inputs = ["0", "1", "2", "100", "200.12"];
18
- expect.assertions(inputs.length);
19
-
20
- inputs.forEach((input) => {
21
- const output = toPositiveNumberWithDefaultZero(input);
22
- expect(output).toBe(Number(input));
23
- });
24
- });
25
-
26
- it("return default number if input is negative number", () => {
27
- const inputs = [-1, -2, -100];
28
- expect.assertions(inputs.length);
29
-
30
- inputs.forEach((input) => {
31
- const output = toPositiveNumberWithDefaultZero(input);
32
- expect(output).toBe(DEFAULT);
33
- });
34
- });
35
-
36
- it("return default number if input is negative number as string", () => {
37
- const inputs = ["-1", "-2", "-100"];
38
- expect.assertions(inputs.length);
39
-
40
- inputs.forEach((input) => {
41
- const output = toPositiveNumberWithDefaultZero(input);
42
- expect(output).toBe(DEFAULT);
43
- });
44
- });
45
-
46
- it("return default if input is not a number or infinite", () => {
47
- const inputs = [
48
- "vfdvf",
49
- null,
50
- undefined,
51
- NaN,
52
- "",
53
- {},
54
- { test: 1 },
55
- [],
56
- [1],
57
- ];
58
-
59
- expect.assertions(inputs.length);
60
-
61
- inputs.forEach((input) => {
62
- const output = toPositiveNumberWithDefaultZero(input);
63
- expect(output).toBe(DEFAULT);
64
- });
65
- });
66
- });
@@ -1,134 +0,0 @@
1
- import { renderHook } from "@testing-library/react-hooks";
2
- import { Dimensions, StatusBar } from "react-native";
3
-
4
- const mockUsePickFromState = jest.fn();
5
- const mockUseIsScreenActive = jest.fn();
6
- const mockGetInitialDimensions = jest.fn();
7
- const mockGetDeviceInfo = jest.fn();
8
-
9
- jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
10
- ...(jest.requireActual("@applicaster/zapp-react-native-redux/hooks") as {}),
11
- usePickFromState: mockUsePickFromState,
12
- }));
13
-
14
- jest.mock("../../../navigation", () => ({
15
- useIsScreenActive: mockUseIsScreenActive,
16
- }));
17
-
18
- jest.mock("../helpers", () => ({
19
- getInitialDimensions: mockGetInitialDimensions,
20
- }));
21
-
22
- jest.mock("../../getDeviceInfo", () => ({
23
- getDeviceInfo: mockGetDeviceInfo,
24
- }));
25
-
26
- const { useDimensions } = require("../useDimensions");
27
-
28
- describe("useDimensions", () => {
29
- const mockDimensions = { width: 100, height: 200, scale: 1, fontScale: 1 };
30
- const mockAppData = { someData: "test" };
31
-
32
- beforeEach(() => {
33
- jest.clearAllMocks();
34
- Dimensions.get = jest.fn().mockReturnValue(mockDimensions);
35
-
36
- Dimensions.addEventListener = jest.fn().mockReturnValue({
37
- remove: jest.fn(),
38
- });
39
-
40
- mockUsePickFromState.mockReturnValue({ appData: mockAppData });
41
- mockUseIsScreenActive.mockReturnValue(true);
42
- mockGetInitialDimensions.mockReturnValue(mockDimensions);
43
- mockGetDeviceInfo.mockReturnValue({ deviceInfo: "testDeviceInfo" });
44
- });
45
-
46
- it("returns correct initial dimensions", () => {
47
- const { result } = renderHook(() =>
48
- useDimensions("window", { fullDimensions: false })
49
- );
50
-
51
- expect(result.current).toEqual({
52
- ...mockDimensions,
53
- statusBarHeight: StatusBar.currentHeight,
54
- });
55
-
56
- expect(mockGetInitialDimensions).toHaveBeenCalledWith("window");
57
- });
58
-
59
- it("calls handler on mount", () => {
60
- renderHook(() => useDimensions("window", { fullDimensions: false }));
61
-
62
- expect(Dimensions.addEventListener).toHaveBeenCalledWith(
63
- "change",
64
- expect.any(Function)
65
- );
66
- });
67
-
68
- it("calls handler on isActive change", () => {
69
- const { rerender } = renderHook(() =>
70
- useDimensions("window", { fullDimensions: false })
71
- );
72
-
73
- mockUseIsScreenActive.mockReturnValue(false);
74
- rerender();
75
-
76
- expect(Dimensions.addEventListener).toHaveBeenCalledWith(
77
- "change",
78
- expect.any(Function)
79
- );
80
- });
81
-
82
- it("handles fullDimensions option", () => {
83
- const { result } = renderHook(() =>
84
- useDimensions("window", { fullDimensions: true })
85
- );
86
-
87
- expect(result.current).toEqual({
88
- ...mockDimensions,
89
- scale: 1,
90
- fontScale: 1,
91
- statusBarHeight: StatusBar.currentHeight,
92
- });
93
- });
94
-
95
- it("handles excludeStatusBar option", () => {
96
- const { result } = renderHook(() =>
97
- useDimensions("window", { excludeStatusBar: true })
98
- );
99
-
100
- expect(result.current.height).toBe(
101
- mockDimensions.height - StatusBar.currentHeight ?? 0
102
- );
103
- });
104
-
105
- it("handles rounded option", () => {
106
- const { result } = renderHook(() =>
107
- useDimensions("window", { rounded: true })
108
- );
109
-
110
- expect(result.current.width).toBe(Math.ceil(mockDimensions.width));
111
- expect(result.current.height).toBe(Math.ceil(mockDimensions.height));
112
- });
113
-
114
- it("handles deviceInfo option", () => {
115
- const { result } = renderHook(() =>
116
- useDimensions("window", { deviceInfo: true })
117
- );
118
-
119
- expect(result.current.deviceInfo).toMatchObject({
120
- deviceInfo: "testDeviceInfo",
121
- });
122
- });
123
-
124
- it("logs deprecation warning when fullDimensions is boolean", () => {
125
- const consoleWarnSpy = jest.spyOn(console, "warn").mockImplementation();
126
- renderHook(() => useDimensions("window", true));
127
-
128
- expect(consoleWarnSpy).toHaveBeenCalledWith(
129
- "Deprecation Warning\nSecond argument is now the options object. {fullDimensions: boolean, ...}"
130
- );
131
-
132
- consoleWarnSpy.mockRestore();
133
- });
134
- });