@symbiote-native/brightness 0.0.1 → 0.1.0

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.
@@ -40,7 +40,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
40
40
  // readonly status = inject(PermissionsService).connect();
41
41
  // // template: {{ status()?.granted }}
42
42
  import { Injectable, signal } from '@angular/core';
43
- import { getPermissionsAsync, requestPermissionsAsync, } from '../../../core';
43
+ import { getPermissionsAsync, requestPermissionsAsync, } from '../../../core/index.js';
44
44
  let PermissionsService = (() => {
45
45
  let _classDecorators = [Injectable({ providedIn: 'root' })];
46
46
  let _classDescriptor;
@@ -28,8 +28,11 @@ export declare function setSystemBrightnessAsync(brightnessValue: number): Promi
28
28
  */
29
29
  export declare function restoreSystemBrightnessAsync(): Promise<void>;
30
30
  /**
31
- * Whether the app is currently controlling the system brightness (as opposed to only its own
32
- * window's brightness). Always `false` on every platform except Android.
31
+ * Whether the activity's window has NO brightness override of its own, so the system-wide
32
+ * brightness is what the screen shows. Native reads `screenBrightness == BRIGHTNESS_OVERRIDE_NONE`,
33
+ * which cannot tell "the app set the system value" apart from "the app never touched brightness" —
34
+ * it reports only that `setBrightnessAsync` is not currently overriding this window.
35
+ * Always `false` on every platform except Android.
33
36
  * @platform android
34
37
  */
35
38
  export declare function isUsingSystemBrightnessAsync(): Promise<boolean>;
@@ -79,8 +79,11 @@ export async function restoreSystemBrightnessAsync() {
79
79
  await expoBrightness.restoreSystemBrightnessAsync();
80
80
  }
81
81
  /**
82
- * Whether the app is currently controlling the system brightness (as opposed to only its own
83
- * window's brightness). Always `false` on every platform except Android.
82
+ * Whether the activity's window has NO brightness override of its own, so the system-wide
83
+ * brightness is what the screen shows. Native reads `screenBrightness == BRIGHTNESS_OVERRIDE_NONE`,
84
+ * which cannot tell "the app set the system value" apart from "the app never touched brightness" —
85
+ * it reports only that `setBrightnessAsync` is not currently overriding this window.
86
+ * Always `false` on every platform except Android.
84
87
  * @platform android
85
88
  */
86
89
  export async function isUsingSystemBrightnessAsync() {
@@ -3,7 +3,7 @@
3
3
  // Mirrors the shape @symbiote-native/cellular's own usePermissions ships in parallel, so both
4
4
  // stay byte-for-byte consistent.
5
5
  import { useCallback, useEffect, useRef, useState } from 'react';
6
- import { getPermissionsAsync, requestPermissionsAsync, } from '../../../core';
6
+ import { getPermissionsAsync, requestPermissionsAsync, } from '../../../core/index.js';
7
7
  export function usePermissions() {
8
8
  const isMounted = useRef(true);
9
9
  const [status, setStatus] = useState(null);
@@ -3,7 +3,7 @@
3
3
  // but there is no ongoing subscription to tear down here, just a one-shot get), then exposes
4
4
  // get/request as imperative callbacks.
5
5
  import { onMounted, ref } from '@vue/runtime-core';
6
- import { getPermissionsAsync, requestPermissionsAsync, } from '../../../core';
6
+ import { getPermissionsAsync, requestPermissionsAsync, } from '../../../core/index.js';
7
7
  export function usePermissions() {
8
8
  const status = ref(null);
9
9
  const get = async () => {
@@ -28,8 +28,11 @@ export declare function setSystemBrightnessAsync(brightnessValue: number): Promi
28
28
  */
29
29
  export declare function restoreSystemBrightnessAsync(): Promise<void>;
30
30
  /**
31
- * Whether the app is currently controlling the system brightness (as opposed to only its own
32
- * window's brightness). Always `false` on every platform except Android.
31
+ * Whether the activity's window has NO brightness override of its own, so the system-wide
32
+ * brightness is what the screen shows. Native reads `screenBrightness == BRIGHTNESS_OVERRIDE_NONE`,
33
+ * which cannot tell "the app set the system value" apart from "the app never touched brightness" —
34
+ * it reports only that `setBrightnessAsync` is not currently overriding this window.
35
+ * Always `false` on every platform except Android.
33
36
  * @platform android
34
37
  */
35
38
  export declare function isUsingSystemBrightnessAsync(): Promise<boolean>;
@@ -79,8 +79,11 @@ export async function restoreSystemBrightnessAsync() {
79
79
  await expoBrightness.restoreSystemBrightnessAsync();
80
80
  }
81
81
  /**
82
- * Whether the app is currently controlling the system brightness (as opposed to only its own
83
- * window's brightness). Always `false` on every platform except Android.
82
+ * Whether the activity's window has NO brightness override of its own, so the system-wide
83
+ * brightness is what the screen shows. Native reads `screenBrightness == BRIGHTNESS_OVERRIDE_NONE`,
84
+ * which cannot tell "the app set the system value" apart from "the app never touched brightness" —
85
+ * it reports only that `setBrightnessAsync` is not currently overriding this window.
86
+ * Always `false` on every platform except Android.
84
87
  * @platform android
85
88
  */
86
89
  export async function isUsingSystemBrightnessAsync() {
@@ -1 +1 @@
1
- {"version":3,"file":"brightness.js","sourceRoot":"","sources":["../../src/core/brightness.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,yFAAyF;AACzF,+FAA+F;AAC/F,+EAA+E;AAC/E,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGlE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAiD,MAAM,SAAS,CAAC;AAExF,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AAE7C,SAAS,eAAe,CAAC,eAAuB,EAAE,UAAkB;IAClE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1D,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,SAAS,CAAC,GAAG,UAAU,0BAA0B,eAAe,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,OAAO,CAAC,CAAC,cAAc,CAAC,kBAAkB,CAAC;AAC7C,CAAC;AAED,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,CAAC,cAAc,CAAC,kBAAkB,EAAE,CAAC;QACvC,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,cAAc,CAAC,kBAAkB,EAAE,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,eAAuB;IAC9D,MAAM,OAAO,GAAG,eAAe,CAAC,eAAe,EAAE,oBAAoB,CAAC,CAAC;IACvE,IAAI,CAAC,cAAc,CAAC,kBAAkB,EAAE,CAAC;QACvC,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,cAAc,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,kBAAkB,EAAE,CAAC;IAC9B,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,wBAAwB,EAAE,CAAC;QAC7C,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,0BAA0B,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,cAAc,CAAC,wBAAwB,EAAE,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,eAAuB;IACpE,MAAM,OAAO,GAAG,eAAe,CAAC,eAAe,EAAE,0BAA0B,CAAC,CAAC;IAC7E,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,wBAAwB,EAAE,CAAC;QAC7C,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,0BAA0B,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,cAAc,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B;IAChD,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,4BAA4B,EAAE,CAAC;QACjD,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,8BAA8B,CAAC,CAAC;IACpF,CAAC;IACD,MAAM,cAAc,CAAC,4BAA4B,EAAE,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B;IAChD,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,4BAA4B,EAAE,CAAC;QACjD,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,8BAA8B,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,cAAc,CAAC,4BAA4B,EAAE,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B;IAChD,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,cAAc,CAAC,OAAO,CAAC;IAChC,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,4BAA4B,EAAE,CAAC;QACjD,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,8BAA8B,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,cAAc,CAAC,4BAA4B,EAAE,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,cAA8B;IAC/E,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,cAAc,KAAK,cAAc,CAAC,OAAO,EAAE,CAAC;QAC3E,OAAO;IACT,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,4BAA4B,EAAE,CAAC;QACjD,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,8BAA8B,CAAC,CAAC;IACpF,CAAC;IACD,MAAM,cAAc,CAAC,4BAA4B,CAAC,cAAc,CAAC,CAAC;AACpE,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,OAAO,cAAc,CAAC,mBAAmB,EAAE,CAAC;AAC9C,CAAC;AAED,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,OAAO,cAAc,CAAC,uBAAuB,EAAE,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAA0C;IAE1C,OAAO,cAAc,CAAC,WAAW,CAAC,0BAA0B,EAAE,QAAQ,CAAC,CAAC;AAC1E,CAAC"}
1
+ {"version":3,"file":"brightness.js","sourceRoot":"","sources":["../../src/core/brightness.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/brightness",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "expo-brightness wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, and Angular adapters. Screen brightness get/set, Android-only system-brightness-mode control, an iOS-only brightness-change listener, and permission get/request.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -40,7 +40,10 @@
40
40
  "src",
41
41
  "build",
42
42
  "build-ngc",
43
- "native-link.json"
43
+ "native-link.json",
44
+ "!src/**/*.test.*",
45
+ "!src/**/*.spec.*",
46
+ "!src/**/*.detox.*"
44
47
  ],
45
48
  "publishConfig": {
46
49
  "access": "public"
@@ -56,7 +59,7 @@
56
59
  "react": ">=19.0.0",
57
60
  "react-native": ">=0.86",
58
61
  "vue": ">=3.5.0",
59
- "@symbiote-native/angular": "0.6.1",
62
+ "@symbiote-native/angular": "0.6.2",
60
63
  "@symbiote-native/react": "0.2.8",
61
64
  "@symbiote-native/vue": "0.3.8"
62
65
  },
@@ -92,10 +95,10 @@
92
95
  "@vue/runtime-core": "^3.5.13",
93
96
  "react": "19.2.3",
94
97
  "typescript": "~6.0.0",
95
- "@symbiote-native/angular": "0.6.1",
96
- "@symbiote-native/test-utils": "0.1.6",
98
+ "@symbiote-native/angular": "0.6.2",
97
99
  "@symbiote-native/engine": "0.1.7",
98
100
  "@symbiote-native/react": "0.2.8",
101
+ "@symbiote-native/test-utils": "0.1.6",
99
102
  "@symbiote-native/vue": "0.3.8"
100
103
  },
101
104
  "scripts": {
@@ -90,8 +90,11 @@ export async function restoreSystemBrightnessAsync(): Promise<void> {
90
90
  }
91
91
 
92
92
  /**
93
- * Whether the app is currently controlling the system brightness (as opposed to only its own
94
- * window's brightness). Always `false` on every platform except Android.
93
+ * Whether the activity's window has NO brightness override of its own, so the system-wide
94
+ * brightness is what the screen shows. Native reads `screenBrightness == BRIGHTNESS_OVERRIDE_NONE`,
95
+ * which cannot tell "the app set the system value" apart from "the app never touched brightness" —
96
+ * it reports only that `setBrightnessAsync` is not currently overriding this window.
97
+ * Always `false` on every platform except Android.
95
98
  * @platform android
96
99
  */
97
100
  export async function isUsingSystemBrightnessAsync(): Promise<boolean> {
@@ -1,107 +0,0 @@
1
- // Co-located Angular-driven test (ADR 0025) for PermissionsService. See battery's
2
- // battery-state.service.test.ts for the shared rationale.
3
-
4
- import '@angular/compiler';
5
- import { Component, inject, type Signal } from '@angular/core';
6
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
7
- import { mount, unmount } from '@symbiote-native/angular';
8
- import { installFabric } from '@symbiote-native/test-utils';
9
- import { PermissionsService } from './index';
10
- import { PermissionStatus, type PermissionResponse } from '../../../core';
11
-
12
- const { getPermissionsAsync, requestPermissionsAsync } = vi.hoisted(() => ({
13
- getPermissionsAsync: vi.fn(),
14
- requestPermissionsAsync: vi.fn(),
15
- }));
16
-
17
- // Same enum-shaped-object mock trick packages/battery/src/angular/services/battery-state.service's
18
- // test uses for BatteryState.
19
- vi.mock('../../../core', () => ({
20
- getPermissionsAsync,
21
- requestPermissionsAsync,
22
- PermissionStatus: { GRANTED: 'granted', DENIED: 'denied', UNDETERMINED: 'undetermined' },
23
- }));
24
-
25
- const GRANTED: PermissionResponse = {
26
- status: PermissionStatus.GRANTED,
27
- granted: true,
28
- canAskAgain: true,
29
- expires: 'never',
30
- };
31
- const DENIED: PermissionResponse = {
32
- status: PermissionStatus.DENIED,
33
- granted: false,
34
- canAskAgain: true,
35
- expires: 'never',
36
- };
37
-
38
- const ROOT_TAG = 973;
39
- const fabric = installFabric();
40
- const tick = (): Promise<void> => new Promise(resolve => setTimeout(resolve, 0));
41
-
42
- let capturedStatus: Signal<PermissionResponse | null> | undefined;
43
- let capturedService: PermissionsService | undefined;
44
-
45
- @Component({
46
- selector: 'symbiote-permissions-host',
47
- standalone: true,
48
- template: '',
49
- })
50
- class PermissionsHost {
51
- readonly service = inject(PermissionsService);
52
- readonly status = this.service.connect();
53
-
54
- constructor() {
55
- capturedStatus = this.status;
56
- capturedService = this.service;
57
- }
58
- }
59
-
60
- beforeEach(() => {
61
- capturedStatus = undefined;
62
- capturedService = undefined;
63
- vi.clearAllMocks();
64
- getPermissionsAsync.mockResolvedValue(GRANTED);
65
- requestPermissionsAsync.mockResolvedValue(GRANTED);
66
- });
67
-
68
- afterEach(() => {
69
- unmount(ROOT_TAG);
70
- fabric.reset();
71
- });
72
-
73
- describe('PermissionsService.connect', () => {
74
- it('reports null before the initial fetch resolves', () => {
75
- mount(ROOT_TAG, PermissionsHost);
76
-
77
- expect(capturedStatus?.()).toBe(null);
78
- });
79
-
80
- it('reports the fetched status once getPermissionsAsync() resolves', async () => {
81
- mount(ROOT_TAG, PermissionsHost);
82
- await tick();
83
-
84
- expect(capturedStatus?.()).toEqual(GRANTED);
85
- expect(getPermissionsAsync).toHaveBeenCalledTimes(1);
86
- });
87
-
88
- it('request() delegates to requestPermissionsAsync and updates the signal', async () => {
89
- mount(ROOT_TAG, PermissionsHost);
90
- await tick();
91
-
92
- requestPermissionsAsync.mockResolvedValueOnce(DENIED);
93
- await capturedService?.request();
94
-
95
- expect(capturedStatus?.()).toEqual(DENIED);
96
- });
97
-
98
- it('get() re-fetches and updates the signal', async () => {
99
- mount(ROOT_TAG, PermissionsHost);
100
- await tick();
101
-
102
- getPermissionsAsync.mockResolvedValueOnce(DENIED);
103
- await capturedService?.get();
104
-
105
- expect(capturedStatus?.()).toEqual(DENIED);
106
- });
107
- });
@@ -1,334 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
-
3
- const FAKE_NATIVE_BRIGHTNESS = {
4
- getBrightnessAsync: vi.fn(async () => 0.5),
5
- setBrightnessAsync: vi.fn(async () => undefined),
6
- getSystemBrightnessAsync: vi.fn(async () => 0.6),
7
- setSystemBrightnessAsync: vi.fn(async () => undefined),
8
- restoreSystemBrightnessAsync: vi.fn(async () => undefined),
9
- isUsingSystemBrightnessAsync: vi.fn(async () => true),
10
- getSystemBrightnessModeAsync: vi.fn(async () => 1),
11
- setSystemBrightnessModeAsync: vi.fn(async () => undefined),
12
- getPermissionsAsync: vi.fn(async () => ({ status: 'granted', granted: true })),
13
- requestPermissionsAsync: vi.fn(async () => ({ status: 'granted', granted: true })),
14
- addListener: vi.fn(() => ({ remove: vi.fn() })),
15
- };
16
-
17
- // The real ExpoBrightness native module only exists on device — resolving it via
18
- // requireNativeModule() at import time would throw in this headless test run, so the
19
- // module-lookup file is faked in place of expo-modules-core's runtime resolution, same pattern
20
- // packages/battery/src/core/battery.test.ts and packages/haptics/src/core/haptics.test.ts use.
21
- vi.mock('./native-module', () => ({
22
- expoBrightness: FAKE_NATIVE_BRIGHTNESS,
23
- }));
24
-
25
- // expo-modules-core's real entry transitively imports 'react-native' for Platform/
26
- // TurboModuleRegistry, whose Flow-typed source Vitest's Oxc transform can't parse — same fake
27
- // packages/haptics/src/core/haptics.test.ts uses, since Platform.OS gates every
28
- // system-brightness branch here.
29
- const fakePlatform = { OS: 'ios' as 'ios' | 'android' };
30
-
31
- vi.mock('expo-modules-core', () => ({
32
- Platform: fakePlatform,
33
- PermissionStatus: { GRANTED: 'granted', DENIED: 'denied', UNDETERMINED: 'undetermined' },
34
- UnavailabilityError: class UnavailabilityError extends Error {
35
- constructor(moduleName: string, propertyName: string) {
36
- super(`${propertyName} is not available on ${moduleName}`);
37
- }
38
- },
39
- }));
40
-
41
- const {
42
- isAvailableAsync,
43
- getBrightnessAsync,
44
- setBrightnessAsync,
45
- getSystemBrightnessAsync,
46
- setSystemBrightnessAsync,
47
- restoreSystemBrightnessAsync,
48
- isUsingSystemBrightnessAsync,
49
- getSystemBrightnessModeAsync,
50
- setSystemBrightnessModeAsync,
51
- getPermissionsAsync,
52
- requestPermissionsAsync,
53
- addBrightnessListener,
54
- } = await import('./brightness');
55
- const { BrightnessMode } = await import('./types');
56
-
57
- afterEach(() => {
58
- fakePlatform.OS = 'ios';
59
- vi.clearAllMocks();
60
- });
61
-
62
- describe('isAvailableAsync', () => {
63
- it('resolves true when the native module implements getBrightnessAsync', async () => {
64
- await expect(isAvailableAsync()).resolves.toBe(true);
65
- });
66
-
67
- it('resolves false when the native method is absent', async () => {
68
- const { getBrightnessAsync: native } = FAKE_NATIVE_BRIGHTNESS;
69
- // @ts-expect-error -- simulating a platform where the native module has no such method
70
- FAKE_NATIVE_BRIGHTNESS.getBrightnessAsync = undefined;
71
-
72
- await expect(isAvailableAsync()).resolves.toBe(false);
73
-
74
- FAKE_NATIVE_BRIGHTNESS.getBrightnessAsync = native;
75
- });
76
- });
77
-
78
- describe('getBrightnessAsync', () => {
79
- it('delegates to the native module', async () => {
80
- await expect(getBrightnessAsync()).resolves.toBe(0.5);
81
- });
82
-
83
- it('throws an UnavailabilityError-shaped error when the native method is absent', async () => {
84
- const { getBrightnessAsync: native } = FAKE_NATIVE_BRIGHTNESS;
85
- // @ts-expect-error -- simulating a platform where the native module has no such method
86
- FAKE_NATIVE_BRIGHTNESS.getBrightnessAsync = undefined;
87
-
88
- await expect(getBrightnessAsync()).rejects.toThrow(
89
- 'getBrightnessAsync is not available on expo-brightness',
90
- );
91
-
92
- FAKE_NATIVE_BRIGHTNESS.getBrightnessAsync = native;
93
- });
94
- });
95
-
96
- describe('setBrightnessAsync', () => {
97
- it('delegates to the native module', async () => {
98
- await setBrightnessAsync(0.4);
99
- expect(FAKE_NATIVE_BRIGHTNESS.setBrightnessAsync).toHaveBeenCalledWith(0.4);
100
- });
101
-
102
- it('clamps a value above 1 down to 1', async () => {
103
- await setBrightnessAsync(1.5);
104
- expect(FAKE_NATIVE_BRIGHTNESS.setBrightnessAsync).toHaveBeenCalledWith(1);
105
- });
106
-
107
- it('clamps a value below 0 up to 0', async () => {
108
- await setBrightnessAsync(-0.5);
109
- expect(FAKE_NATIVE_BRIGHTNESS.setBrightnessAsync).toHaveBeenCalledWith(0);
110
- });
111
-
112
- it('throws a TypeError when the clamped value is NaN', async () => {
113
- await expect(setBrightnessAsync(NaN)).rejects.toThrow(
114
- 'setBrightnessAsync cannot be called with NaN',
115
- );
116
- expect(FAKE_NATIVE_BRIGHTNESS.setBrightnessAsync).not.toHaveBeenCalled();
117
- });
118
-
119
- it('throws an UnavailabilityError-shaped error when the native method is absent', async () => {
120
- const { setBrightnessAsync: native } = FAKE_NATIVE_BRIGHTNESS;
121
- // @ts-expect-error -- simulating a platform where the native module has no such method
122
- FAKE_NATIVE_BRIGHTNESS.setBrightnessAsync = undefined;
123
-
124
- await expect(setBrightnessAsync(0.5)).rejects.toThrow(
125
- 'setBrightnessAsync is not available on expo-brightness',
126
- );
127
-
128
- FAKE_NATIVE_BRIGHTNESS.setBrightnessAsync = native;
129
- });
130
- });
131
-
132
- describe('getSystemBrightnessAsync', () => {
133
- it('delegates to getBrightnessAsync on non-Android platforms', async () => {
134
- fakePlatform.OS = 'ios';
135
- await expect(getSystemBrightnessAsync()).resolves.toBe(0.5);
136
- expect(FAKE_NATIVE_BRIGHTNESS.getSystemBrightnessAsync).not.toHaveBeenCalled();
137
- });
138
-
139
- it('delegates to the native module on Android', async () => {
140
- fakePlatform.OS = 'android';
141
- await expect(getSystemBrightnessAsync()).resolves.toBe(0.6);
142
- });
143
-
144
- it('throws an UnavailabilityError-shaped error on Android when the native method is absent', async () => {
145
- fakePlatform.OS = 'android';
146
- const { getSystemBrightnessAsync: native } = FAKE_NATIVE_BRIGHTNESS;
147
- // @ts-expect-error -- simulating an Android build missing this native method
148
- FAKE_NATIVE_BRIGHTNESS.getSystemBrightnessAsync = undefined;
149
-
150
- await expect(getSystemBrightnessAsync()).rejects.toThrow(
151
- 'getSystemBrightnessAsync is not available on expo-brightness',
152
- );
153
-
154
- FAKE_NATIVE_BRIGHTNESS.getSystemBrightnessAsync = native;
155
- });
156
- });
157
-
158
- describe('setSystemBrightnessAsync', () => {
159
- it('delegates to setBrightnessAsync on non-Android platforms', async () => {
160
- fakePlatform.OS = 'ios';
161
- await setSystemBrightnessAsync(0.3);
162
- expect(FAKE_NATIVE_BRIGHTNESS.setBrightnessAsync).toHaveBeenCalledWith(0.3);
163
- expect(FAKE_NATIVE_BRIGHTNESS.setSystemBrightnessAsync).not.toHaveBeenCalled();
164
- });
165
-
166
- it('delegates to the native module on Android', async () => {
167
- fakePlatform.OS = 'android';
168
- await setSystemBrightnessAsync(0.3);
169
- expect(FAKE_NATIVE_BRIGHTNESS.setSystemBrightnessAsync).toHaveBeenCalledWith(0.3);
170
- });
171
-
172
- it('clamps out-of-range values before delegating', async () => {
173
- fakePlatform.OS = 'android';
174
- await setSystemBrightnessAsync(2);
175
- expect(FAKE_NATIVE_BRIGHTNESS.setSystemBrightnessAsync).toHaveBeenCalledWith(1);
176
- });
177
-
178
- it('throws a TypeError when the clamped value is NaN', async () => {
179
- await expect(setSystemBrightnessAsync(NaN)).rejects.toThrow(
180
- 'setSystemBrightnessAsync cannot be called with NaN',
181
- );
182
- });
183
-
184
- it('throws an UnavailabilityError-shaped error on Android when the native method is absent', async () => {
185
- fakePlatform.OS = 'android';
186
- const { setSystemBrightnessAsync: native } = FAKE_NATIVE_BRIGHTNESS;
187
- // @ts-expect-error -- simulating an Android build missing this native method
188
- FAKE_NATIVE_BRIGHTNESS.setSystemBrightnessAsync = undefined;
189
-
190
- await expect(setSystemBrightnessAsync(0.5)).rejects.toThrow(
191
- 'setSystemBrightnessAsync is not available on expo-brightness',
192
- );
193
-
194
- FAKE_NATIVE_BRIGHTNESS.setSystemBrightnessAsync = native;
195
- });
196
- });
197
-
198
- describe('restoreSystemBrightnessAsync', () => {
199
- it('no-ops on non-Android platforms without calling the native module', async () => {
200
- fakePlatform.OS = 'ios';
201
- await restoreSystemBrightnessAsync();
202
- expect(FAKE_NATIVE_BRIGHTNESS.restoreSystemBrightnessAsync).not.toHaveBeenCalled();
203
- });
204
-
205
- it('delegates to the native module on Android', async () => {
206
- fakePlatform.OS = 'android';
207
- await restoreSystemBrightnessAsync();
208
- expect(FAKE_NATIVE_BRIGHTNESS.restoreSystemBrightnessAsync).toHaveBeenCalledTimes(1);
209
- });
210
-
211
- it('throws an UnavailabilityError-shaped error on Android when the native method is absent', async () => {
212
- fakePlatform.OS = 'android';
213
- const { restoreSystemBrightnessAsync: native } = FAKE_NATIVE_BRIGHTNESS;
214
- // @ts-expect-error -- simulating an Android build missing this native method
215
- FAKE_NATIVE_BRIGHTNESS.restoreSystemBrightnessAsync = undefined;
216
-
217
- await expect(restoreSystemBrightnessAsync()).rejects.toThrow(
218
- 'restoreSystemBrightnessAsync is not available on expo-brightness',
219
- );
220
-
221
- FAKE_NATIVE_BRIGHTNESS.restoreSystemBrightnessAsync = native;
222
- });
223
- });
224
-
225
- describe('isUsingSystemBrightnessAsync', () => {
226
- it('resolves false on non-Android platforms without calling the native module', async () => {
227
- fakePlatform.OS = 'ios';
228
- await expect(isUsingSystemBrightnessAsync()).resolves.toBe(false);
229
- expect(FAKE_NATIVE_BRIGHTNESS.isUsingSystemBrightnessAsync).not.toHaveBeenCalled();
230
- });
231
-
232
- it('delegates to the native module on Android', async () => {
233
- fakePlatform.OS = 'android';
234
- await expect(isUsingSystemBrightnessAsync()).resolves.toBe(true);
235
- });
236
-
237
- it('throws an UnavailabilityError-shaped error on Android when the native method is absent', async () => {
238
- fakePlatform.OS = 'android';
239
- const { isUsingSystemBrightnessAsync: native } = FAKE_NATIVE_BRIGHTNESS;
240
- // @ts-expect-error -- simulating an Android build missing this native method
241
- FAKE_NATIVE_BRIGHTNESS.isUsingSystemBrightnessAsync = undefined;
242
-
243
- await expect(isUsingSystemBrightnessAsync()).rejects.toThrow(
244
- 'isUsingSystemBrightnessAsync is not available on expo-brightness',
245
- );
246
-
247
- FAKE_NATIVE_BRIGHTNESS.isUsingSystemBrightnessAsync = native;
248
- });
249
- });
250
-
251
- describe('getSystemBrightnessModeAsync', () => {
252
- it('resolves UNKNOWN on non-Android platforms without calling the native module', async () => {
253
- fakePlatform.OS = 'ios';
254
- await expect(getSystemBrightnessModeAsync()).resolves.toBe(BrightnessMode.UNKNOWN);
255
- expect(FAKE_NATIVE_BRIGHTNESS.getSystemBrightnessModeAsync).not.toHaveBeenCalled();
256
- });
257
-
258
- it('delegates to the native module on Android', async () => {
259
- fakePlatform.OS = 'android';
260
- await expect(getSystemBrightnessModeAsync()).resolves.toBe(1);
261
- });
262
-
263
- it('throws an UnavailabilityError-shaped error on Android when the native method is absent', async () => {
264
- fakePlatform.OS = 'android';
265
- const { getSystemBrightnessModeAsync: native } = FAKE_NATIVE_BRIGHTNESS;
266
- // @ts-expect-error -- simulating an Android build missing this native method
267
- FAKE_NATIVE_BRIGHTNESS.getSystemBrightnessModeAsync = undefined;
268
-
269
- await expect(getSystemBrightnessModeAsync()).rejects.toThrow(
270
- 'getSystemBrightnessModeAsync is not available on expo-brightness',
271
- );
272
-
273
- FAKE_NATIVE_BRIGHTNESS.getSystemBrightnessModeAsync = native;
274
- });
275
- });
276
-
277
- describe('setSystemBrightnessModeAsync', () => {
278
- it('no-ops on non-Android platforms without calling the native module', async () => {
279
- fakePlatform.OS = 'ios';
280
- await setSystemBrightnessModeAsync(BrightnessMode.AUTOMATIC);
281
- expect(FAKE_NATIVE_BRIGHTNESS.setSystemBrightnessModeAsync).not.toHaveBeenCalled();
282
- });
283
-
284
- it('no-ops on Android when passed UNKNOWN', async () => {
285
- fakePlatform.OS = 'android';
286
- await setSystemBrightnessModeAsync(BrightnessMode.UNKNOWN);
287
- expect(FAKE_NATIVE_BRIGHTNESS.setSystemBrightnessModeAsync).not.toHaveBeenCalled();
288
- });
289
-
290
- it('delegates to the native module on Android with a concrete mode', async () => {
291
- fakePlatform.OS = 'android';
292
- await setSystemBrightnessModeAsync(BrightnessMode.MANUAL);
293
- expect(FAKE_NATIVE_BRIGHTNESS.setSystemBrightnessModeAsync).toHaveBeenCalledWith(
294
- BrightnessMode.MANUAL,
295
- );
296
- });
297
-
298
- it('throws an UnavailabilityError-shaped error on Android when the native method is absent', async () => {
299
- fakePlatform.OS = 'android';
300
- const { setSystemBrightnessModeAsync: native } = FAKE_NATIVE_BRIGHTNESS;
301
- // @ts-expect-error -- simulating an Android build missing this native method
302
- FAKE_NATIVE_BRIGHTNESS.setSystemBrightnessModeAsync = undefined;
303
-
304
- await expect(setSystemBrightnessModeAsync(BrightnessMode.MANUAL)).rejects.toThrow(
305
- 'setSystemBrightnessModeAsync is not available on expo-brightness',
306
- );
307
-
308
- FAKE_NATIVE_BRIGHTNESS.setSystemBrightnessModeAsync = native;
309
- });
310
- });
311
-
312
- describe('getPermissionsAsync', () => {
313
- it('passes straight through to the native module', async () => {
314
- await expect(getPermissionsAsync()).resolves.toEqual({ status: 'granted', granted: true });
315
- });
316
- });
317
-
318
- describe('requestPermissionsAsync', () => {
319
- it('passes straight through to the native module', async () => {
320
- await expect(requestPermissionsAsync()).resolves.toEqual({ status: 'granted', granted: true });
321
- });
322
- });
323
-
324
- describe('addBrightnessListener', () => {
325
- it('subscribes through the Expo.brightnessDidChange event name', () => {
326
- const listener = vi.fn();
327
- addBrightnessListener(listener);
328
-
329
- expect(FAKE_NATIVE_BRIGHTNESS.addListener).toHaveBeenCalledWith(
330
- 'Expo.brightnessDidChange',
331
- listener,
332
- );
333
- });
334
- });
@@ -1,100 +0,0 @@
1
- // Co-located React-driven test (ADR 0025) for usePermissions. See battery's
2
- // use-battery-state.test.tsx for the shared rationale (mocks `core`, not expo-modules-core
3
- // internals).
4
-
5
- import { createElement, type ReactElement } from 'react';
6
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
7
- import { mount, unmount, View } from '@symbiote-native/react';
8
- import { installFabric } from '@symbiote-native/test-utils';
9
- import { usePermissions } from './index';
10
- import { PermissionStatus, type PermissionResponse } from '../../../core';
11
-
12
- const { getPermissionsAsync, requestPermissionsAsync } = vi.hoisted(() => ({
13
- getPermissionsAsync: vi.fn(),
14
- requestPermissionsAsync: vi.fn(),
15
- }));
16
-
17
- // Same enum-shaped-object mock trick packages/battery/src/react/hooks/use-battery-state's test
18
- // uses for BatteryState — the mock factory's runtime object stands in for the real enum
19
- // (imported here purely for its type), so `PermissionStatus.GRANTED` still type-checks.
20
- vi.mock('../../../core', () => ({
21
- getPermissionsAsync,
22
- requestPermissionsAsync,
23
- PermissionStatus: { GRANTED: 'granted', DENIED: 'denied', UNDETERMINED: 'undetermined' },
24
- }));
25
-
26
- const ROOT_TAG = 953;
27
-
28
- const GRANTED: PermissionResponse = {
29
- status: PermissionStatus.GRANTED,
30
- granted: true,
31
- canAskAgain: true,
32
- expires: 'never',
33
- };
34
- const DENIED: PermissionResponse = {
35
- status: PermissionStatus.DENIED,
36
- granted: false,
37
- canAskAgain: true,
38
- expires: 'never',
39
- };
40
-
41
- const results: (PermissionResponse | null)[] = [];
42
- let latestRequest: (() => Promise<PermissionResponse>) | undefined;
43
- let latestGet: (() => Promise<PermissionResponse>) | undefined;
44
-
45
- function Probe(): ReactElement {
46
- const [status, request, get] = usePermissions();
47
- results.push(status);
48
- latestRequest = request;
49
- latestGet = get;
50
- return createElement(View);
51
- }
52
-
53
- const fabric = installFabric();
54
-
55
- beforeEach(() => {
56
- fabric.reset();
57
- results.length = 0;
58
- latestRequest = undefined;
59
- latestGet = undefined;
60
- vi.clearAllMocks();
61
- getPermissionsAsync.mockResolvedValue(GRANTED);
62
- requestPermissionsAsync.mockResolvedValue(GRANTED);
63
- });
64
-
65
- afterEach(() => unmount(ROOT_TAG));
66
-
67
- describe('usePermissions', () => {
68
- it('starts at null before the initial fetch resolves', () => {
69
- mount(ROOT_TAG, createElement(Probe));
70
-
71
- expect(results[results.length - 1]).toBe(null);
72
- });
73
-
74
- it('fetches the permission status once on mount', async () => {
75
- mount(ROOT_TAG, createElement(Probe));
76
-
77
- await vi.waitFor(() => expect(results[results.length - 1]).toEqual(GRANTED));
78
- expect(getPermissionsAsync).toHaveBeenCalledTimes(1);
79
- });
80
-
81
- it('request() delegates to requestPermissionsAsync and updates the status', async () => {
82
- mount(ROOT_TAG, createElement(Probe));
83
- await vi.waitFor(() => expect(results[results.length - 1]).toEqual(GRANTED));
84
-
85
- requestPermissionsAsync.mockResolvedValueOnce(DENIED);
86
- await latestRequest?.();
87
-
88
- await vi.waitFor(() => expect(results[results.length - 1]).toEqual(DENIED));
89
- });
90
-
91
- it('get() re-fetches and updates the status', async () => {
92
- mount(ROOT_TAG, createElement(Probe));
93
- await vi.waitFor(() => expect(results[results.length - 1]).toEqual(GRANTED));
94
-
95
- getPermissionsAsync.mockResolvedValueOnce(DENIED);
96
- await latestGet?.();
97
-
98
- await vi.waitFor(() => expect(results[results.length - 1]).toEqual(DENIED));
99
- });
100
- });
@@ -1,99 +0,0 @@
1
- // Co-located Vue-driven test (ADR 0025) for usePermissions. See battery's
2
- // use-battery-state.test.ts for the shared rationale.
3
-
4
- import { defineComponent, h } from '@vue/runtime-core';
5
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
6
- import { mount, unmount } from '@symbiote-native/vue';
7
- import { installFabric } from '@symbiote-native/test-utils';
8
- import { usePermissions } from './index';
9
- import { PermissionStatus, type PermissionResponse } from '../../../core';
10
-
11
- const { getPermissionsAsync, requestPermissionsAsync } = vi.hoisted(() => ({
12
- getPermissionsAsync: vi.fn(),
13
- requestPermissionsAsync: vi.fn(),
14
- }));
15
-
16
- // Same enum-shaped-object mock trick packages/battery/src/vue/composables/use-battery-state's
17
- // test uses for BatteryState.
18
- vi.mock('../../../core', () => ({
19
- getPermissionsAsync,
20
- requestPermissionsAsync,
21
- PermissionStatus: { GRANTED: 'granted', DENIED: 'denied', UNDETERMINED: 'undetermined' },
22
- }));
23
-
24
- const GRANTED: PermissionResponse = {
25
- status: PermissionStatus.GRANTED,
26
- granted: true,
27
- canAskAgain: true,
28
- expires: 'never',
29
- };
30
- const DENIED: PermissionResponse = {
31
- status: PermissionStatus.DENIED,
32
- granted: false,
33
- canAskAgain: true,
34
- expires: 'never',
35
- };
36
-
37
- const ROOT_TAG = 9953;
38
- const fabric = installFabric();
39
-
40
- beforeEach(() => {
41
- fabric.reset();
42
- vi.clearAllMocks();
43
- getPermissionsAsync.mockResolvedValue(GRANTED);
44
- requestPermissionsAsync.mockResolvedValue(GRANTED);
45
- });
46
-
47
- afterEach(() => unmount(ROOT_TAG));
48
-
49
- function mountPermissions(): ReturnType<typeof usePermissions> {
50
- let result: ReturnType<typeof usePermissions> | undefined;
51
- mount(
52
- ROOT_TAG,
53
- defineComponent({
54
- setup: () => {
55
- result = usePermissions();
56
- return () => h('symbiote-text', {}, 'brightness');
57
- },
58
- }),
59
- );
60
- if (result === undefined) {
61
- throw new Error('setup() did not run');
62
- }
63
- return result;
64
- }
65
-
66
- describe('usePermissions (Vue)', () => {
67
- it('starts at null before the initial fetch resolves', () => {
68
- const { status } = mountPermissions();
69
-
70
- expect(status.value).toBe(null);
71
- });
72
-
73
- it('fetches the permission status once on mount', async () => {
74
- const { status } = mountPermissions();
75
-
76
- await vi.waitFor(() => expect(status.value).toEqual(GRANTED));
77
- expect(getPermissionsAsync).toHaveBeenCalledTimes(1);
78
- });
79
-
80
- it('request() delegates to requestPermissionsAsync and updates the status', async () => {
81
- const { status, request } = mountPermissions();
82
- await vi.waitFor(() => expect(status.value).toEqual(GRANTED));
83
-
84
- requestPermissionsAsync.mockResolvedValueOnce(DENIED);
85
- await request();
86
-
87
- expect(status.value).toEqual(DENIED);
88
- });
89
-
90
- it('get() re-fetches and updates the status', async () => {
91
- const { status, get } = mountPermissions();
92
- await vi.waitFor(() => expect(status.value).toEqual(GRANTED));
93
-
94
- getPermissionsAsync.mockResolvedValueOnce(DENIED);
95
- await get();
96
-
97
- expect(status.value).toEqual(DENIED);
98
- });
99
- });