@react-native-firebase/app 26.4.0 → 27.0.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.
- package/CHANGELOG.md +48 -0
- package/README.md +10 -27
- package/RNFBApp.podspec +13 -5
- package/android/build.gradle +3 -0
- package/android/src/main/java/io/invertase/firebase/common/RNFBHandleCollisionException.kt +29 -0
- package/android/src/main/java/io/invertase/firebase/common/RNFBHandleMap.kt +146 -0
- package/android/src/main/java/io/invertase/firebase/common/TaskExecutorService.kt +156 -0
- package/android/src/main/java/io/invertase/firebase/common/UniversalFirebaseModule.kt +44 -0
- package/android/src/main/java/io/invertase/firebase/common/UniversalFirebasePreferences.kt +100 -0
- package/android/src/reactnative/java/io/invertase/firebase/app/NativeRNFBTurboApp.kt +250 -0
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseApp.kt +64 -0
- package/android/src/reactnative/java/io/invertase/firebase/app/{ReactNativeFirebaseAppInitProvider.java → ReactNativeFirebaseAppInitProvider.kt} +3 -4
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.kt +47 -0
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppRegistrar.kt +33 -0
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseVersion.java +1 -1
- package/android/src/reactnative/java/io/invertase/firebase/common/RCTConvertFirebase.kt +185 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEvent.kt +35 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.kt +662 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseJSON.kt +103 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseMeta.kt +96 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseModule.kt +140 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.kt +109 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/SharedUtils.kt +451 -0
- package/android/src/reactnative/java/io/invertase/firebase/interfaces/{ContextProvider.java → ContextProvider.kt} +8 -8
- package/android/src/reactnative/java/io/invertase/firebase/interfaces/{NativeError.java → NativeError.kt} +8 -8
- package/android/src/reactnative/java/io/invertase/firebase/interfaces/{NativeEvent.java → NativeEvent.kt} +6 -6
- package/android/src/reactnative/java/io/invertase/firebase/utils/NativeRNFBTurboUtils.kt +219 -0
- package/android/src/test/java/expo/core/ModuleRegistry.java +9 -0
- package/android/src/test/java/io/invertase/firebase/app/NativeRNFBTurboAppTest.java +182 -59
- package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppComponentsJavaCompatibilityTest.java +70 -0
- package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppJavaCompatibilityTest.java +60 -0
- package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackageTest.java +165 -0
- package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppTest.kt +167 -0
- package/android/src/test/java/io/invertase/firebase/common/RCTConvertFirebaseJavaCompatibilityTest.java +112 -0
- package/android/src/test/java/io/invertase/firebase/common/RCTConvertFirebaseTest.kt +317 -0
- package/android/src/test/java/io/invertase/firebase/common/RNFBHandleMapTest.kt +309 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitterJavaCompatibilityTest.java +176 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitterTest.java +143 -12
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventTest.kt +61 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONJavaCompatibilityTest.java +85 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONTest.kt +296 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseMetaJavaCompatibilityTest.java +67 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseMetaTest.kt +246 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseModuleTest.kt +254 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebasePreferencesJavaCompatibilityTest.java +87 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebasePreferencesTest.kt +260 -0
- package/android/src/test/java/io/invertase/firebase/common/SharedUtilsJavaCompatibilityTest.java +255 -0
- package/android/src/test/java/io/invertase/firebase/common/SharedUtilsTest.kt +674 -0
- package/android/src/test/java/io/invertase/firebase/common/TaskExecutorServiceTest.kt +290 -0
- package/android/src/test/java/io/invertase/firebase/common/UniversalFirebaseModuleJavaCompatibilityTest.java +178 -0
- package/android/src/test/java/io/invertase/firebase/common/UniversalFirebasePreferencesJavaCompatibilityTest.java +99 -0
- package/android/src/test/java/io/invertase/firebase/common/UniversalFirebasePreferencesTest.kt +217 -0
- package/android/src/test/java/io/invertase/firebase/commoncompat/ReactNativeFirebaseModuleJavaCompatibilityTest.java +176 -0
- package/android/src/test/java/io/invertase/firebase/commoncompat/ReactNativeFirebaseModuleKotlinCompatibilityTest.kt +52 -0
- package/android/src/test/java/io/invertase/firebase/interfaces/InterfacesJavaCompatibilityTest.java +144 -0
- package/android/src/test/java/io/invertase/firebase/interfaces/NativeEventTest.kt +56 -0
- package/android/src/test/java/io/invertase/firebase/utils/NativeRNFBTurboUtilsTest.java +517 -21
- package/dist/module/FirebaseApp.js +10 -0
- package/dist/module/FirebaseApp.js.map +1 -1
- package/dist/module/common/deeps.js +3 -0
- package/dist/module/common/deeps.js.map +1 -1
- package/dist/module/internal/FirebaseModule.js.map +1 -1
- package/dist/module/internal/RNFBNativeEventEmitter.js +12 -1
- package/dist/module/internal/RNFBNativeEventEmitter.js.map +1 -1
- package/dist/module/internal/SharedEventEmitter.js +3 -1
- package/dist/module/internal/SharedEventEmitter.js.map +1 -1
- package/dist/module/internal/index.js +1 -0
- package/dist/module/internal/index.js.map +1 -1
- package/dist/module/internal/registry/app.js +7 -1
- package/dist/module/internal/registry/app.js.map +1 -1
- package/dist/module/types/app.js.map +1 -1
- package/dist/module/types/internal.js +2 -0
- package/dist/module/version.js +1 -1
- package/dist/typescript/lib/FirebaseApp.d.ts +7 -0
- package/dist/typescript/lib/FirebaseApp.d.ts.map +1 -1
- package/dist/typescript/lib/common/deeps.d.ts.map +1 -1
- package/dist/typescript/lib/internal/FirebaseModule.d.ts +2 -3
- package/dist/typescript/lib/internal/FirebaseModule.d.ts.map +1 -1
- package/dist/typescript/lib/internal/NativeModules.d.ts +4 -1
- package/dist/typescript/lib/internal/NativeModules.d.ts.map +1 -1
- package/dist/typescript/lib/internal/RNFBNativeEventEmitter.d.ts +2 -2
- package/dist/typescript/lib/internal/RNFBNativeEventEmitter.d.ts.map +1 -1
- package/dist/typescript/lib/internal/SharedEventEmitter.d.ts +3 -3
- package/dist/typescript/lib/internal/SharedEventEmitter.d.ts.map +1 -1
- package/dist/typescript/lib/internal/index.d.ts +1 -0
- package/dist/typescript/lib/internal/index.d.ts.map +1 -1
- package/dist/typescript/lib/internal/registry/app.d.ts.map +1 -1
- package/dist/typescript/lib/types/app.d.ts +10 -3
- package/dist/typescript/lib/types/app.d.ts.map +1 -1
- package/dist/typescript/lib/types/internal.d.ts +12 -0
- package/dist/typescript/lib/types/internal.d.ts.map +1 -1
- package/dist/typescript/lib/version.d.ts +1 -1
- package/firebase-schema.json +4 -0
- package/firebase_spm.rb +552 -96
- package/ios/RNFBApp/RCTConvert+FIRApp.h +2 -5
- package/ios/RNFBApp/RCTConvert+FIRApp.m +11 -6
- package/ios/RNFBApp/RCTConvert+FIROptions.h +2 -5
- package/ios/RNFBApp/RCTConvert+FIROptions.m +11 -10
- package/ios/RNFBApp/RCTConvertFIRApp.swift +86 -0
- package/ios/RNFBApp/RCTConvertFIROptions.swift +259 -0
- package/ios/RNFBApp/RNFBAppCustomAuthDomains.swift +63 -0
- package/ios/RNFBApp/RNFBAppInitializeOptionsMapper.swift +113 -0
- package/ios/RNFBApp/RNFBAppLogLevelMapper.swift +53 -0
- package/ios/RNFBApp/RNFBAppModule+CustomAuthDomain.m +35 -0
- package/ios/RNFBApp/RNFBAppModule.h +6 -2
- package/ios/RNFBApp/RNFBAppModule.mm +65 -228
- package/ios/RNFBApp/RNFBAppModuleFirebase.swift +439 -0
- package/ios/RNFBApp/RNFBAppModuleImplementation.h +68 -0
- package/ios/RNFBApp/RNFBAppModuleImplementation.m +195 -0
- package/ios/RNFBApp/RNFBHandleMap.m +27 -56
- package/ios/RNFBApp/RNFBHandleMapStorage.swift +90 -0
- package/ios/RNFBApp/RNFBInitializeAppArguments.swift +82 -0
- package/ios/RNFBApp/RNFBJSON.m +22 -38
- package/ios/RNFBApp/RNFBJSONImplementation.swift +71 -0
- package/ios/RNFBApp/RNFBMeta.m +24 -26
- package/ios/RNFBApp/RNFBMetaStorage.swift +76 -0
- package/ios/RNFBApp/RNFBNullSentinelDecoding.swift +135 -0
- package/ios/RNFBApp/RNFBNullSentinelInterceptor.h +30 -3
- package/ios/RNFBApp/RNFBNullSentinelInterceptor.m +28 -5
- package/ios/RNFBApp/RNFBPreferences.m +22 -20
- package/ios/RNFBApp/RNFBPreferencesStorage.swift +101 -0
- package/ios/RNFBApp/RNFBRCTEventEmitter.m +36 -93
- package/ios/RNFBApp/RNFBRCTEventEmitterCore.swift +161 -0
- package/ios/RNFBApp/RNFBSharedUtils.h +2 -5
- package/ios/RNFBApp/RNFBSharedUtils.m +109 -198
- package/ios/RNFBApp/RNFBSharedUtilsConfig.swift +72 -0
- package/ios/RNFBApp/RNFBSharedUtilsFIRApp.swift +271 -0
- package/ios/RNFBApp/RNFBSharedUtilsFormatting.swift +59 -0
- package/ios/RNFBApp/RNFBSharedUtilsPromiseRejection.swift +88 -0
- package/ios/RNFBApp/RNFBUtilsHelpers.swift +116 -0
- package/ios/RNFBApp/RNFBUtilsModule+Foundation.m +44 -0
- package/ios/RNFBApp/RNFBUtilsModule+PhotoAssets.m +47 -0
- package/ios/RNFBApp/RNFBUtilsModule.h +11 -1
- package/ios/RNFBApp/RNFBUtilsModule.mm +10 -85
- package/ios/RNFBApp/RNFBUtilsModuleImplementation.h +32 -0
- package/ios/RNFBApp/RNFBUtilsModuleImplementation.m +56 -0
- package/ios/RNFBApp/RNFBVersion.m +1 -1
- package/ios/RNFBApp.xcodeproj/project.pbxproj +100 -0
- package/ios/RNFBAppUnitTests/HostStubs/FirebaseCore/FIRApp.m +171 -0
- package/ios/RNFBAppUnitTests/HostStubs/FirebaseCore/FirebaseCore.h +78 -0
- package/ios/RNFBAppUnitTests/HostStubs/FirebaseInstallations/FIRInstallations.m +7 -0
- package/ios/RNFBAppUnitTests/HostStubs/FirebaseInstallations/FirebaseInstallations.h +8 -0
- package/ios/RNFBAppUnitTests/HostStubs/RNFBAppModuleHostStub.m +55 -0
- package/ios/RNFBAppUnitTests/HostStubs/RNFBAppTurboModules.h +89 -0
- package/ios/RNFBAppUnitTests/HostStubs/RNFBAppTurboModules.mm +30 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTBridge.h +19 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTBridge.m +32 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTBridgeModule.h +19 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTConvert.h +28 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTConvert.m +23 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTEventEmitter.h +9 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTInvalidating.h +24 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTUtils.h +9 -0
- package/ios/RNFBAppUnitTests/HostStubs/module.modulemap +13 -0
- package/ios/RNFBAppUnitTests/RCTConvertFIRAppFacadeTests.m +61 -0
- package/ios/RNFBAppUnitTests/RCTConvertFIRAppTests.swift +73 -0
- package/ios/RNFBAppUnitTests/RCTConvertFIROptionsFacadeTests.m +57 -0
- package/ios/RNFBAppUnitTests/RCTConvertFIROptionsTests.swift +243 -0
- package/ios/RNFBAppUnitTests/RNFBAppCustomAuthDomainsFacadeTests.m +73 -0
- package/ios/RNFBAppUnitTests/RNFBAppCustomAuthDomainsTests.swift +70 -0
- package/ios/RNFBAppUnitTests/RNFBAppInitializeOptionsMapperTests.swift +190 -0
- package/ios/RNFBAppUnitTests/RNFBAppLogLevelFacadeTests.m +76 -0
- package/ios/RNFBAppUnitTests/RNFBAppLogLevelMapperTests.swift +59 -0
- package/ios/RNFBAppUnitTests/RNFBAppModuleFirebaseFacadeTests.m +215 -0
- package/ios/RNFBAppUnitTests/RNFBAppModuleFirebaseTests.swift +430 -0
- package/ios/RNFBAppUnitTests/RNFBAppModuleLifecycleTests.m +206 -0
- package/ios/RNFBAppUnitTests/RNFBAppModuleShellTests.mm +367 -0
- package/ios/RNFBAppUnitTests/RNFBAppUnitTests.xcodeproj/project.pbxproj +355 -2
- package/ios/RNFBAppUnitTests/RNFBFirebaseAppClientTests.swift +165 -0
- package/ios/RNFBAppUnitTests/RNFBHandleMapStorageTests.swift +121 -0
- package/ios/RNFBAppUnitTests/RNFBInitializeAppArgumentsTests.swift +256 -0
- package/ios/RNFBAppUnitTests/RNFBJSONImplementationTests.swift +126 -0
- package/ios/RNFBAppUnitTests/RNFBJSONTests.m +172 -0
- package/ios/RNFBAppUnitTests/RNFBMetaStorageTests.swift +106 -0
- package/ios/RNFBAppUnitTests/RNFBMetaTests.m +65 -0
- package/ios/RNFBAppUnitTests/RNFBNullSentinelDecodingTests.swift +286 -0
- package/ios/RNFBAppUnitTests/RNFBNullSentinelInterceptorTests.m +312 -0
- package/ios/RNFBAppUnitTests/RNFBPreferencesStorageTests.swift +105 -0
- package/ios/RNFBAppUnitTests/RNFBPreferencesTests.m +110 -0
- package/ios/RNFBAppUnitTests/RNFBRCTEventEmitterCoreTests.swift +163 -0
- package/ios/RNFBAppUnitTests/RNFBRCTEventEmitterFacadeTests.m +141 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsConfigFacadeTests.m +100 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsConfigTests.swift +234 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsFIRAppFacadeTests.m +145 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsFIRAppTests.swift +173 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsFormattingFacadeTests.m +38 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsFormattingTests.swift +82 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsNullSentinelTests.m +35 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsPromiseRejectionFacadeTests.m +107 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsPromiseRejectionTests.swift +133 -0
- package/ios/RNFBAppUnitTests/RNFBUtilsHelpersTests.swift +144 -0
- package/ios/RNFBAppUnitTests/RNFBUtilsModuleFacadeTests.m +72 -0
- package/ios/RNFBAppUnitTests/RNFBUtilsModuleShellTests.mm +282 -0
- package/ios/RNFBFirebase/Package.swift +53 -0
- package/ios/RNFBFirebase/Sources/RNFBFirebase/RNFBFirebase.swift +285 -0
- package/ios/RNFBFirebase/Sources/RNFBFirebaseBridge/Public/.gitkeep +0 -0
- package/ios/RNFBFirebase/Sources/RNFBFirebaseBridge/RNFBFirebaseBridge.m +169 -0
- package/ios/RNFBFirebase/Sources/RNFBFirebaseBridge/include/RNFBFirebaseBridge.h +52 -0
- package/ios/RNFBFirebaseUnitTests/RNFBAppDynamicFacadeTests.swift +240 -0
- package/{android/src/main/java/io/invertase/firebase/common/RNFBHandleCollisionException.java → ios/RNFBFirebaseUnitTests/RNFBFirebaseClientImport.swift} +23 -14
- package/ios/RNFBFirebaseUnitTests/RNFBFirebaseUnitTests.xcodeproj/project.pbxproj +588 -0
- package/ios/RNFBFirebaseUnitTests/RNFBFirebaseUnitTests.xcodeproj/xcshareddata/xcschemes/RNFBFirebaseUnitTests.xcscheme +83 -0
- package/ios_config.sh +50 -22
- package/lib/FirebaseApp.ts +10 -0
- package/lib/common/deeps.ts +3 -0
- package/lib/internal/FirebaseModule.ts +6 -3
- package/lib/internal/NativeModules.ts +4 -1
- package/lib/internal/RNFBNativeEventEmitter.ts +14 -5
- package/lib/internal/SharedEventEmitter.ts +5 -1
- package/lib/internal/index.ts +1 -0
- package/lib/internal/react-native-vendor-emitter.d.ts +11 -0
- package/lib/internal/registry/app.ts +7 -1
- package/lib/types/app.ts +10 -3
- package/lib/types/internal.ts +19 -0
- package/lib/version.ts +1 -1
- package/package.json +8 -8
- package/plugin/build/ios/appDelegate.js +2 -2
- package/plugin/build/ios/podfile.js +16 -16
- package/plugin/build/pluginConfig.d.ts +4 -2
- package/plugin/src/ios/appDelegate.ts +2 -2
- package/plugin/src/ios/podfile.ts +20 -23
- package/plugin/src/pluginConfig.ts +4 -2
- package/android/src/main/java/io/invertase/firebase/common/RNFBHandleMap.java +0 -150
- package/android/src/main/java/io/invertase/firebase/common/TaskExecutorService.java +0 -148
- package/android/src/main/java/io/invertase/firebase/common/UniversalFirebaseModule.java +0 -62
- package/android/src/main/java/io/invertase/firebase/common/UniversalFirebasePreferences.java +0 -91
- package/android/src/reactnative/java/io/invertase/firebase/app/NativeRNFBTurboApp.java +0 -224
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseApp.java +0 -46
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.java +0 -49
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppRegistrar.java +0 -35
- package/android/src/reactnative/java/io/invertase/firebase/common/RCTConvertFirebase.java +0 -192
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEvent.java +0 -53
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.java +0 -606
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseJSON.java +0 -109
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseMeta.java +0 -101
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseModule.java +0 -146
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.java +0 -96
- package/android/src/reactnative/java/io/invertase/firebase/common/SharedUtils.java +0 -441
- package/android/src/reactnative/java/io/invertase/firebase/utils/NativeRNFBTurboUtils.java +0 -223
- package/android/src/test/java/io/invertase/firebase/common/RNFBHandleMapTest.java +0 -275
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONTest.java +0 -108
- package/android/src/test/java/io/invertase/firebase/common/TaskExecutorServiceTest.java +0 -97
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
package io.invertase.firebase.common
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import org.json.JSONObject
|
|
21
|
+
import org.junit.After
|
|
22
|
+
import org.junit.Assert.assertEquals
|
|
23
|
+
import org.junit.Assert.assertFalse
|
|
24
|
+
import org.junit.Assert.assertNotSame
|
|
25
|
+
import org.junit.Assert.assertSame
|
|
26
|
+
import org.junit.Assert.assertTrue
|
|
27
|
+
import org.junit.Assert.fail
|
|
28
|
+
import org.junit.Before
|
|
29
|
+
import org.junit.Test
|
|
30
|
+
import org.mockito.ArgumentMatchers.anyInt
|
|
31
|
+
import org.mockito.ArgumentMatchers.anyString
|
|
32
|
+
import org.mockito.Mockito.mock
|
|
33
|
+
import org.mockito.Mockito.`when`
|
|
34
|
+
import java.util.Collections
|
|
35
|
+
import java.util.concurrent.CountDownLatch
|
|
36
|
+
import java.util.concurrent.ExecutorService
|
|
37
|
+
import java.util.concurrent.LinkedBlockingQueue
|
|
38
|
+
import java.util.concurrent.RejectedExecutionException
|
|
39
|
+
import java.util.concurrent.RejectedExecutionHandler
|
|
40
|
+
import java.util.concurrent.SynchronousQueue
|
|
41
|
+
import java.util.concurrent.ThreadPoolExecutor
|
|
42
|
+
import java.util.concurrent.TimeUnit
|
|
43
|
+
import java.util.concurrent.atomic.AtomicBoolean
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Plain JUnit4 + Mockito (AndroidTest-AD-1). Constructor reads pool sizing from
|
|
47
|
+
* [ReactNativeFirebaseJSON]; stub that away so we never touch Android's unmocked
|
|
48
|
+
* `org.json.JSONObject`.
|
|
49
|
+
*/
|
|
50
|
+
class TaskExecutorServiceTest {
|
|
51
|
+
private lateinit var jsonObjectField: java.lang.reflect.Field
|
|
52
|
+
private var originalJsonObject: Any? = null
|
|
53
|
+
private val configuration = HashMap<String, Int>()
|
|
54
|
+
|
|
55
|
+
@Before
|
|
56
|
+
fun setUp() {
|
|
57
|
+
val jsonObject = mock(JSONObject::class.java)
|
|
58
|
+
`when`(jsonObject.optInt(anyString(), anyInt()))
|
|
59
|
+
.thenAnswer { invocation ->
|
|
60
|
+
configuration[invocation.getArgument(0)] ?: invocation.getArgument(1)
|
|
61
|
+
}
|
|
62
|
+
val json = ReactNativeFirebaseJSON.getSharedInstance()
|
|
63
|
+
jsonObjectField = ReactNativeFirebaseJSON::class.java.getDeclaredField("jsonObject")
|
|
64
|
+
jsonObjectField.isAccessible = true
|
|
65
|
+
originalJsonObject = jsonObjectField.get(json)
|
|
66
|
+
jsonObjectField.set(json, jsonObject)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@After
|
|
70
|
+
fun tearDown() {
|
|
71
|
+
jsonObjectField.set(ReactNativeFirebaseJSON.getSharedInstance(), originalJsonObject)
|
|
72
|
+
configuration.clear()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@Test
|
|
76
|
+
fun transactionalExecutorRunsSubmittedWork() {
|
|
77
|
+
val service = TaskExecutorService("TestTransactionalRuns")
|
|
78
|
+
val executor = service.getTransactionalExecutor()
|
|
79
|
+
val latch = CountDownLatch(1)
|
|
80
|
+
|
|
81
|
+
executor.execute(latch::countDown)
|
|
82
|
+
|
|
83
|
+
assertTrue("work submitted before shutdown runs", latch.await(5, TimeUnit.SECONDS))
|
|
84
|
+
assertSame(executor, service.getExecutor())
|
|
85
|
+
service.shutdown()
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@Test
|
|
89
|
+
fun transactionalExecutorIsSingleThreadedNonDaemonAndOrdered() {
|
|
90
|
+
val service = TaskExecutorService("TestTransactionalSemantics")
|
|
91
|
+
val executor = service.getTransactionalExecutor()
|
|
92
|
+
val firstStarted = CountDownLatch(1)
|
|
93
|
+
val releaseFirst = CountDownLatch(1)
|
|
94
|
+
val finished = CountDownLatch(2)
|
|
95
|
+
val order = Collections.synchronizedList(ArrayList<Int>())
|
|
96
|
+
var threadName = ""
|
|
97
|
+
var daemon = true
|
|
98
|
+
|
|
99
|
+
executor.execute {
|
|
100
|
+
threadName = Thread.currentThread().name
|
|
101
|
+
daemon = Thread.currentThread().isDaemon
|
|
102
|
+
order.add(1)
|
|
103
|
+
firstStarted.countDown()
|
|
104
|
+
releaseFirst.await()
|
|
105
|
+
finished.countDown()
|
|
106
|
+
}
|
|
107
|
+
assertTrue(firstStarted.await(5, TimeUnit.SECONDS))
|
|
108
|
+
executor.execute {
|
|
109
|
+
order.add(2)
|
|
110
|
+
finished.countDown()
|
|
111
|
+
}
|
|
112
|
+
assertEquals(listOf(1), order)
|
|
113
|
+
releaseFirst.countDown()
|
|
114
|
+
|
|
115
|
+
assertTrue(finished.await(5, TimeUnit.SECONDS))
|
|
116
|
+
assertEquals(listOf(1, 2), order)
|
|
117
|
+
assertTrue(threadName.matches(Regex("pool-\\d+-thread-1")))
|
|
118
|
+
assertFalse(daemon)
|
|
119
|
+
service.shutdown()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@Test
|
|
123
|
+
fun configuredPooledExecutorPreservesPoolSettingsAndFallbackExecution() {
|
|
124
|
+
configuration["android_task_executor_maximum_pool_size"] = 1
|
|
125
|
+
configuration["android_task_executor_keep_alive_seconds"] = 7
|
|
126
|
+
val service = TaskExecutorService("TestPooledFallback")
|
|
127
|
+
val executor = service.getExecutor(false, "") as ThreadPoolExecutor
|
|
128
|
+
val blockingStarted = CountDownLatch(1)
|
|
129
|
+
val releaseBlocking = CountDownLatch(1)
|
|
130
|
+
val fallbackRan = CountDownLatch(1)
|
|
131
|
+
|
|
132
|
+
executor.execute {
|
|
133
|
+
blockingStarted.countDown()
|
|
134
|
+
releaseBlocking.await()
|
|
135
|
+
}
|
|
136
|
+
assertTrue(blockingStarted.await(5, TimeUnit.SECONDS))
|
|
137
|
+
executor.execute(fallbackRan::countDown)
|
|
138
|
+
|
|
139
|
+
assertTrue(fallbackRan.await(5, TimeUnit.SECONDS))
|
|
140
|
+
assertEquals(0, executor.corePoolSize)
|
|
141
|
+
assertEquals(1, executor.maximumPoolSize)
|
|
142
|
+
assertEquals(7L, executor.getKeepAliveTime(TimeUnit.SECONDS))
|
|
143
|
+
assertTrue(executor.queue is SynchronousQueue<*>)
|
|
144
|
+
releaseBlocking.countDown()
|
|
145
|
+
service.shutdown()
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@Test
|
|
149
|
+
fun defaultExecutorUsesConfiguredPoolWhenMaximumExceedsOne() {
|
|
150
|
+
configuration["android_task_executor_maximum_pool_size"] = 2
|
|
151
|
+
val service = TaskExecutorService("TestDefaultPool")
|
|
152
|
+
|
|
153
|
+
val executor = service.getExecutor() as ThreadPoolExecutor
|
|
154
|
+
|
|
155
|
+
assertEquals(0, executor.corePoolSize)
|
|
156
|
+
assertEquals(2, executor.maximumPoolSize)
|
|
157
|
+
assertTrue(executor.queue is SynchronousQueue<*>)
|
|
158
|
+
service.shutdown()
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@Test
|
|
162
|
+
fun transactionalIdentifiersAreCachedAndDistinctWhenPoolingEnabled() {
|
|
163
|
+
val service = TaskExecutorService("TestIdentifiers")
|
|
164
|
+
val first = service.getTransactionalExecutor("one")
|
|
165
|
+
|
|
166
|
+
assertSame(first, service.getTransactionalExecutor("one"))
|
|
167
|
+
assertNotSame(first, service.getTransactionalExecutor("two"))
|
|
168
|
+
service.shutdown()
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@Test
|
|
172
|
+
fun transactionalIdentifierIsIgnoredWhenPoolingDisabled() {
|
|
173
|
+
configuration["android_task_executor_maximum_pool_size"] = 0
|
|
174
|
+
val service = TaskExecutorService("TestZeroPool")
|
|
175
|
+
|
|
176
|
+
assertSame(
|
|
177
|
+
service.getTransactionalExecutor("one"),
|
|
178
|
+
service.getTransactionalExecutor("two"),
|
|
179
|
+
)
|
|
180
|
+
service.shutdown()
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
@Test
|
|
184
|
+
fun executorNamesPreserveTransactionalAndPooledShapes() {
|
|
185
|
+
val service = TaskExecutorService("TestNames")
|
|
186
|
+
|
|
187
|
+
assertEquals("TestNamesTransactionalExecutorid", service.getExecutorName(true, "id"))
|
|
188
|
+
assertEquals("TestNamesExecutorid", service.getExecutorName(false, "id"))
|
|
189
|
+
service.shutdown()
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@Test
|
|
193
|
+
fun concurrentLookupReturnsOneSharedExecutor() {
|
|
194
|
+
val service = TaskExecutorService("TestConcurrentLookup")
|
|
195
|
+
val start = CountDownLatch(1)
|
|
196
|
+
val done = CountDownLatch(2)
|
|
197
|
+
val executors = Collections.synchronizedList(ArrayList<ExecutorService>())
|
|
198
|
+
val threads =
|
|
199
|
+
List(2) {
|
|
200
|
+
Thread {
|
|
201
|
+
start.await()
|
|
202
|
+
executors.add(service.getTransactionalExecutor())
|
|
203
|
+
done.countDown()
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
threads.forEach(Thread::start)
|
|
208
|
+
start.countDown()
|
|
209
|
+
|
|
210
|
+
assertTrue(done.await(5, TimeUnit.SECONDS))
|
|
211
|
+
assertSame(executors[0], executors[1])
|
|
212
|
+
service.shutdown()
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
@Test
|
|
216
|
+
fun removeExecutorShutsDownKnownExecutorAndIgnoresMissingName() {
|
|
217
|
+
val service = TaskExecutorService("TestRemove")
|
|
218
|
+
val executor = service.getTransactionalExecutor()
|
|
219
|
+
|
|
220
|
+
service.removeExecutor("missing")
|
|
221
|
+
assertFalse(executor.isShutdown)
|
|
222
|
+
service.removeExecutor(service.getExecutorName(true, ""))
|
|
223
|
+
|
|
224
|
+
assertTrue(executor.isShutdown)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
@Test
|
|
228
|
+
fun shutdownShutsDownOwnExecutorsAndOnlyRemovesForeignMapping() {
|
|
229
|
+
val foreignService = TaskExecutorService("TestForeign")
|
|
230
|
+
val foreignExecutor = foreignService.getTransactionalExecutor()
|
|
231
|
+
val service = TaskExecutorService("TestShutdown")
|
|
232
|
+
val ownExecutor = service.getTransactionalExecutor()
|
|
233
|
+
|
|
234
|
+
service.shutdown()
|
|
235
|
+
|
|
236
|
+
assertTrue(ownExecutor.isShutdown)
|
|
237
|
+
assertFalse(foreignExecutor.isShutdown)
|
|
238
|
+
assertNotSame(foreignExecutor, foreignService.getTransactionalExecutor())
|
|
239
|
+
foreignExecutor.shutdownNow()
|
|
240
|
+
foreignService.shutdown()
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
@Test
|
|
244
|
+
fun transactionalExecutorUsesUnboundedQueueAndAbortSemanticsBeforeShutdown() {
|
|
245
|
+
val service = TaskExecutorService("TestTransactionalShape")
|
|
246
|
+
val executor = service.getTransactionalExecutor() as ThreadPoolExecutor
|
|
247
|
+
|
|
248
|
+
assertEquals(1, executor.corePoolSize)
|
|
249
|
+
assertEquals(1, executor.maximumPoolSize)
|
|
250
|
+
assertTrue(executor.queue is LinkedBlockingQueue<*>)
|
|
251
|
+
|
|
252
|
+
val field = TaskExecutorService::class.java.getDeclaredField("discardAfterShutdown")
|
|
253
|
+
field.isAccessible = true
|
|
254
|
+
val handler = field.get(null) as RejectedExecutionHandler
|
|
255
|
+
try {
|
|
256
|
+
handler.rejectedExecution({}, executor)
|
|
257
|
+
fail("expected RejectedExecutionException")
|
|
258
|
+
} catch (exception: RejectedExecutionException) {
|
|
259
|
+
assertTrue(exception.message!!.contains("rejected from"))
|
|
260
|
+
}
|
|
261
|
+
service.shutdown()
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
@Test
|
|
265
|
+
fun transactionalExecutorDiscardsWorkSubmittedAfterShutdown() {
|
|
266
|
+
val service = TaskExecutorService("TestTransactionalShutdown")
|
|
267
|
+
val executor = service.getTransactionalExecutor()
|
|
268
|
+
service.shutdown()
|
|
269
|
+
val ran = AtomicBoolean(false)
|
|
270
|
+
|
|
271
|
+
// Must not throw RejectedExecutionException - this is the crash path hit when a
|
|
272
|
+
// play-services Task completes after module invalidation has shut the executor down.
|
|
273
|
+
executor.execute { ran.set(true) }
|
|
274
|
+
|
|
275
|
+
assertFalse("work submitted after shutdown is discarded", ran.get())
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
@Test
|
|
279
|
+
fun pooledExecutorDiscardsWorkSubmittedAfterShutdown() {
|
|
280
|
+
val service = TaskExecutorService("TestPooledShutdown")
|
|
281
|
+
val executor = service.getExecutor(false, "")
|
|
282
|
+
service.shutdown()
|
|
283
|
+
val ran = AtomicBoolean(false)
|
|
284
|
+
|
|
285
|
+
// Exercises the executeInFallback handler's shutdown guard.
|
|
286
|
+
executor.execute { ran.set(true) }
|
|
287
|
+
|
|
288
|
+
assertFalse("work submitted after shutdown is discarded", ran.get())
|
|
289
|
+
}
|
|
290
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
package io.invertase.firebase.common;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import static org.junit.Assert.assertEquals;
|
|
20
|
+
import static org.junit.Assert.assertFalse;
|
|
21
|
+
import static org.junit.Assert.assertNotSame;
|
|
22
|
+
import static org.junit.Assert.assertNull;
|
|
23
|
+
import static org.junit.Assert.assertSame;
|
|
24
|
+
import static org.junit.Assert.assertThrows;
|
|
25
|
+
import static org.junit.Assert.assertTrue;
|
|
26
|
+
import static org.mockito.Mockito.mock;
|
|
27
|
+
import static org.mockito.Mockito.when;
|
|
28
|
+
|
|
29
|
+
import android.content.Context;
|
|
30
|
+
import java.lang.reflect.Constructor;
|
|
31
|
+
import java.lang.reflect.Field;
|
|
32
|
+
import java.lang.reflect.Method;
|
|
33
|
+
import java.lang.reflect.Modifier;
|
|
34
|
+
import java.util.Arrays;
|
|
35
|
+
import java.util.HashMap;
|
|
36
|
+
import java.util.Map;
|
|
37
|
+
import java.util.concurrent.ExecutorService;
|
|
38
|
+
import javax.annotation.OverridingMethodsMustInvokeSuper;
|
|
39
|
+
import org.json.JSONObject;
|
|
40
|
+
import org.junit.After;
|
|
41
|
+
import org.junit.Before;
|
|
42
|
+
import org.junit.Test;
|
|
43
|
+
|
|
44
|
+
/** Verifies the Kotlin port remains source- and binary-compatible with Java callers. */
|
|
45
|
+
public class UniversalFirebaseModuleJavaCompatibilityTest {
|
|
46
|
+
private Field jsonObjectField;
|
|
47
|
+
private Object originalJsonObject;
|
|
48
|
+
|
|
49
|
+
@Before
|
|
50
|
+
public void setUp() throws Exception {
|
|
51
|
+
ReactNativeFirebaseJSON json = ReactNativeFirebaseJSON.getSharedInstance();
|
|
52
|
+
jsonObjectField = ReactNativeFirebaseJSON.class.getDeclaredField("jsonObject");
|
|
53
|
+
jsonObjectField.setAccessible(true);
|
|
54
|
+
originalJsonObject = jsonObjectField.get(json);
|
|
55
|
+
jsonObjectField.set(json, mock(JSONObject.class));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@After
|
|
59
|
+
public void tearDown() throws Exception {
|
|
60
|
+
jsonObjectField.set(ReactNativeFirebaseJSON.getSharedInstance(), originalJsonObject);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@Test
|
|
64
|
+
public void preservesPublicOpenJavaAbi() throws Exception {
|
|
65
|
+
Class<UniversalFirebaseModule> type = UniversalFirebaseModule.class;
|
|
66
|
+
Constructor<UniversalFirebaseModule> constructor =
|
|
67
|
+
type.getConstructor(Context.class, String.class);
|
|
68
|
+
|
|
69
|
+
assertTrue(Modifier.isPublic(type.getModifiers()));
|
|
70
|
+
assertFalse(Modifier.isFinal(type.getModifiers()));
|
|
71
|
+
assertTrue(Modifier.isPublic(constructor.getModifiers()));
|
|
72
|
+
|
|
73
|
+
for (String methodName :
|
|
74
|
+
Arrays.asList(
|
|
75
|
+
"getContext",
|
|
76
|
+
"getApplicationContext",
|
|
77
|
+
"getExecutor",
|
|
78
|
+
"getName",
|
|
79
|
+
"onTearDown",
|
|
80
|
+
"getConstants")) {
|
|
81
|
+
Method method = type.getDeclaredMethod(methodName);
|
|
82
|
+
assertTrue(methodName, Modifier.isPublic(method.getModifiers()));
|
|
83
|
+
assertFalse(methodName, Modifier.isFinal(method.getModifiers()));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
assertEquals(Context.class, type.getDeclaredMethod("getContext").getReturnType());
|
|
87
|
+
assertEquals(Context.class, type.getDeclaredMethod("getApplicationContext").getReturnType());
|
|
88
|
+
assertEquals(ExecutorService.class, type.getDeclaredMethod("getExecutor").getReturnType());
|
|
89
|
+
assertEquals(String.class, type.getDeclaredMethod("getName").getReturnType());
|
|
90
|
+
assertEquals(void.class, type.getDeclaredMethod("onTearDown").getReturnType());
|
|
91
|
+
assertEquals(Map.class, type.getDeclaredMethod("getConstants").getReturnType());
|
|
92
|
+
assertTrue(
|
|
93
|
+
type.getDeclaredMethod("onTearDown")
|
|
94
|
+
.isAnnotationPresent(OverridingMethodsMustInvokeSuper.class));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@Test
|
|
98
|
+
public void preservesNullPermissivenessNameAndContextBehavior() {
|
|
99
|
+
UniversalFirebaseModule nullModule = new UniversalFirebaseModule(null, null);
|
|
100
|
+
|
|
101
|
+
assertNull(nullModule.getContext());
|
|
102
|
+
assertEquals("UniversalnullModule", nullModule.getName());
|
|
103
|
+
assertThrows(NullPointerException.class, nullModule::getApplicationContext);
|
|
104
|
+
nullModule.onTearDown();
|
|
105
|
+
|
|
106
|
+
Context context = mock(Context.class);
|
|
107
|
+
Context applicationContext = mock(Context.class);
|
|
108
|
+
when(context.getApplicationContext()).thenReturn(applicationContext);
|
|
109
|
+
UniversalFirebaseModule module = new UniversalFirebaseModule(context, "App");
|
|
110
|
+
|
|
111
|
+
assertSame(context, module.getContext());
|
|
112
|
+
assertSame(applicationContext, module.getApplicationContext());
|
|
113
|
+
assertEquals("UniversalAppModule", module.getName());
|
|
114
|
+
module.onTearDown();
|
|
115
|
+
|
|
116
|
+
Context contextWithNoApplicationContext = mock(Context.class);
|
|
117
|
+
UniversalFirebaseModule nullApplicationContextModule =
|
|
118
|
+
new UniversalFirebaseModule(contextWithNoApplicationContext, "NullApplicationContext");
|
|
119
|
+
assertNull(nullApplicationContextModule.getApplicationContext());
|
|
120
|
+
nullApplicationContextModule.onTearDown();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@Test
|
|
124
|
+
public void constructorUsesVirtualGetNameDuringSuperConstruction() throws Exception {
|
|
125
|
+
ConstructorDispatchModule module = new ConstructorDispatchModule(null, "Ignored");
|
|
126
|
+
Field executorServiceField = UniversalFirebaseModule.class.getDeclaredField("executorService");
|
|
127
|
+
executorServiceField.setAccessible(true);
|
|
128
|
+
Object executorService = executorServiceField.get(module);
|
|
129
|
+
Field nameField = TaskExecutorService.class.getDeclaredField("name");
|
|
130
|
+
nameField.setAccessible(true);
|
|
131
|
+
|
|
132
|
+
assertEquals("DuringSuper", nameField.get(executorService));
|
|
133
|
+
assertEquals("AfterSuper", module.getName());
|
|
134
|
+
module.onTearDown();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@Test
|
|
138
|
+
public void exposesExecutorAndTearDownShutsItDown() {
|
|
139
|
+
UniversalFirebaseModule module = new UniversalFirebaseModule(null, "Shutdown");
|
|
140
|
+
ExecutorService executor = module.getExecutor();
|
|
141
|
+
|
|
142
|
+
assertSame(executor, module.getExecutor());
|
|
143
|
+
assertFalse(executor.isShutdown());
|
|
144
|
+
|
|
145
|
+
module.onTearDown();
|
|
146
|
+
|
|
147
|
+
assertTrue(executor.isShutdown());
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@Test
|
|
151
|
+
public void constantsAreFreshMutableHashMaps() {
|
|
152
|
+
UniversalFirebaseModule module = new UniversalFirebaseModule(null, "Constants");
|
|
153
|
+
Map<String, Object> first = module.getConstants();
|
|
154
|
+
Map<String, Object> second = module.getConstants();
|
|
155
|
+
|
|
156
|
+
assertTrue(first instanceof HashMap);
|
|
157
|
+
assertTrue(second instanceof HashMap);
|
|
158
|
+
assertNotSame(first, second);
|
|
159
|
+
first.put("mutable", true);
|
|
160
|
+
assertEquals(true, first.get("mutable"));
|
|
161
|
+
assertTrue(second.isEmpty());
|
|
162
|
+
module.onTearDown();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private static final class ConstructorDispatchModule extends UniversalFirebaseModule {
|
|
166
|
+
private String state;
|
|
167
|
+
|
|
168
|
+
ConstructorDispatchModule(Context context, String serviceName) {
|
|
169
|
+
super(context, serviceName);
|
|
170
|
+
state = "AfterSuper";
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@Override
|
|
174
|
+
public String getName() {
|
|
175
|
+
return state == null ? "DuringSuper" : state;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
package io.invertase.firebase.common;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import static org.junit.Assert.assertFalse;
|
|
20
|
+
import static org.junit.Assert.assertNull;
|
|
21
|
+
import static org.junit.Assert.assertSame;
|
|
22
|
+
import static org.mockito.Mockito.mock;
|
|
23
|
+
import static org.mockito.Mockito.never;
|
|
24
|
+
import static org.mockito.Mockito.times;
|
|
25
|
+
import static org.mockito.Mockito.verify;
|
|
26
|
+
import static org.mockito.Mockito.when;
|
|
27
|
+
|
|
28
|
+
import android.content.SharedPreferences;
|
|
29
|
+
import java.lang.reflect.Field;
|
|
30
|
+
import org.junit.Before;
|
|
31
|
+
import org.junit.Test;
|
|
32
|
+
|
|
33
|
+
/** Proves the Kotlin port preserves Java null calls and remove ownership. */
|
|
34
|
+
public class UniversalFirebasePreferencesJavaCompatibilityTest {
|
|
35
|
+
private SharedPreferences preferences;
|
|
36
|
+
private SharedPreferences.Editor editor;
|
|
37
|
+
private UniversalFirebasePreferences subject;
|
|
38
|
+
|
|
39
|
+
@Before
|
|
40
|
+
public void setUp() throws Exception {
|
|
41
|
+
preferences = mock(SharedPreferences.class);
|
|
42
|
+
editor = mock(SharedPreferences.Editor.class);
|
|
43
|
+
when(preferences.edit()).thenReturn(editor);
|
|
44
|
+
when(editor.putBoolean(null, true)).thenReturn(editor);
|
|
45
|
+
when(editor.putInt(null, 42)).thenReturn(editor);
|
|
46
|
+
when(editor.putLong(null, 4294967296L)).thenReturn(editor);
|
|
47
|
+
when(editor.putString(null, null)).thenReturn(editor);
|
|
48
|
+
when(editor.remove(null)).thenReturn(editor);
|
|
49
|
+
when(preferences.contains(null)).thenReturn(false);
|
|
50
|
+
when(preferences.getBoolean(null, true)).thenReturn(false);
|
|
51
|
+
when(preferences.getInt(null, 42)).thenReturn(42);
|
|
52
|
+
when(preferences.getLong(null, 4294967296L)).thenReturn(4294967296L);
|
|
53
|
+
when(preferences.getString(null, null)).thenReturn(null);
|
|
54
|
+
|
|
55
|
+
subject = new UniversalFirebasePreferences();
|
|
56
|
+
Field field = UniversalFirebasePreferences.class.getDeclaredField("preferences");
|
|
57
|
+
field.setAccessible(true);
|
|
58
|
+
field.set(subject, preferences);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@Test
|
|
62
|
+
public void publicAccessorsAcceptNullKeysFromJava() {
|
|
63
|
+
assertFalse(subject.contains(null));
|
|
64
|
+
subject.setBooleanValue(null, true);
|
|
65
|
+
assertFalse(subject.getBooleanValue(null, true));
|
|
66
|
+
subject.setIntValue(null, 42);
|
|
67
|
+
subject.getIntValue(null, 42);
|
|
68
|
+
subject.setLongValue(null, 4294967296L);
|
|
69
|
+
subject.getLongValue(null, 4294967296L);
|
|
70
|
+
|
|
71
|
+
verify(preferences).contains(null);
|
|
72
|
+
verify(editor).putBoolean(null, true);
|
|
73
|
+
verify(preferences).getBoolean(null, true);
|
|
74
|
+
verify(editor).putInt(null, 42);
|
|
75
|
+
verify(preferences).getInt(null, 42);
|
|
76
|
+
verify(editor).putLong(null, 4294967296L);
|
|
77
|
+
verify(preferences).getLong(null, 4294967296L);
|
|
78
|
+
verify(editor, times(3)).apply();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@Test
|
|
82
|
+
public void stringAccessorsAcceptNullsAndCanReturnNullToJava() {
|
|
83
|
+
subject.setStringValue(null, null);
|
|
84
|
+
|
|
85
|
+
assertNull(subject.getStringValue(null, null));
|
|
86
|
+
verify(editor).putString(null, null);
|
|
87
|
+
verify(editor).apply();
|
|
88
|
+
verify(preferences).getString(null, null);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@Test
|
|
92
|
+
public void removeAcceptsNullAndLeavesEditorCompletionToJavaCaller() {
|
|
93
|
+
assertSame(editor, subject.remove(null));
|
|
94
|
+
|
|
95
|
+
verify(editor).remove(null);
|
|
96
|
+
verify(editor, never()).apply();
|
|
97
|
+
verify(editor, never()).commit();
|
|
98
|
+
}
|
|
99
|
+
}
|