|
72 | 72 | using ObjCRuntime; |
73 | 73 | #endif |
74 | 74 |
|
| 75 | +#if ENABLE_RUNTIME_DRIFT_CASE_CLOUDFIRESTORE_NAMED_DATABASE |
| 76 | +using Firebase.CloudFirestore; |
| 77 | +using Foundation; |
| 78 | +using ObjCRuntime; |
| 79 | +#endif |
| 80 | + |
75 | 81 | #if ENABLE_RUNTIME_DRIFT_CASE_CLOUDFUNCTIONS_USEFUNCTIONSEMULATORORIGIN |
76 | 82 | using Firebase.CloudFunctions; |
77 | 83 | using Foundation; |
@@ -1875,6 +1881,119 @@ void OnMarshalObjectiveCException(object? sender, MarshalObjectiveCExceptionEven |
1875 | 1881 |
|
1876 | 1882 | #endif |
1877 | 1883 |
|
| 1884 | +#if ENABLE_RUNTIME_DRIFT_CASE_CLOUDFIRESTORE_NAMED_DATABASE |
| 1885 | + static Task<string> VerifyCloudFirestoreNamedDatabaseAsync() |
| 1886 | + { |
| 1887 | + const string firestoreForDatabaseSelector = "firestoreForDatabase:"; |
| 1888 | + const string firestoreForAppDatabaseSelector = "firestoreForApp:database:"; |
| 1889 | + const string databaseId = "(default)"; |
| 1890 | + |
| 1891 | + var databaseSignature = typeof(Firestore).GetMethod( |
| 1892 | + nameof(Firestore.Create), |
| 1893 | + BindingFlags.Static | BindingFlags.Public, |
| 1894 | + binder: null, |
| 1895 | + types: new[] { typeof(string) }, |
| 1896 | + modifiers: null); |
| 1897 | + if (databaseSignature?.ReturnType != typeof(Firestore)) |
| 1898 | + { |
| 1899 | + throw new InvalidOperationException( |
| 1900 | + $"Expected managed API '{typeof(Firestore).FullName}.{nameof(Firestore.Create)}({typeof(string).FullName})' " + |
| 1901 | + $"to return '{typeof(Firestore).FullName}' for selector '{firestoreForDatabaseSelector}', " + |
| 1902 | + $"observed '{databaseSignature?.ReturnType.FullName ?? "<missing>"}'."); |
| 1903 | + } |
| 1904 | + |
| 1905 | + var appDatabaseSignature = typeof(Firestore).GetMethod( |
| 1906 | + nameof(Firestore.Create), |
| 1907 | + BindingFlags.Static | BindingFlags.Public, |
| 1908 | + binder: null, |
| 1909 | + types: new[] { typeof(Firebase.Core.App), typeof(string) }, |
| 1910 | + modifiers: null); |
| 1911 | + if (appDatabaseSignature?.ReturnType != typeof(Firestore)) |
| 1912 | + { |
| 1913 | + throw new InvalidOperationException( |
| 1914 | + $"Expected managed API '{typeof(Firestore).FullName}.{nameof(Firestore.Create)}({typeof(Firebase.Core.App).FullName}, {typeof(string).FullName})' " + |
| 1915 | + $"to return '{typeof(Firestore).FullName}' for selector '{firestoreForAppDatabaseSelector}', " + |
| 1916 | + $"observed '{appDatabaseSignature?.ReturnType.FullName ?? "<missing>"}'."); |
| 1917 | + } |
| 1918 | + |
| 1919 | + var defaultApp = Firebase.Core.App.DefaultInstance |
| 1920 | + ?? throw new InvalidOperationException("Firebase.Core.App.DefaultInstance returned null after App.Configure()."); |
| 1921 | + NSException? marshaledException = null; |
| 1922 | + MarshalObjectiveCExceptionMode? marshaledExceptionMode = null; |
| 1923 | + |
| 1924 | + void OnMarshalObjectiveCException(object? sender, MarshalObjectiveCExceptionEventArgs args) |
| 1925 | + { |
| 1926 | + marshaledException ??= args.Exception; |
| 1927 | + marshaledExceptionMode ??= args.ExceptionMode; |
| 1928 | + } |
| 1929 | + |
| 1930 | + Runtime.MarshalObjectiveCException += OnMarshalObjectiveCException; |
| 1931 | + try |
| 1932 | + { |
| 1933 | + Firestore? defaultNamedDatabase = null; |
| 1934 | + Firestore? appNamedDatabase = null; |
| 1935 | + try |
| 1936 | + { |
| 1937 | + defaultNamedDatabase = Firestore.Create(databaseId); |
| 1938 | + appNamedDatabase = Firestore.Create(defaultApp, databaseId); |
| 1939 | + } |
| 1940 | + catch (ObjCException ex) |
| 1941 | + { |
| 1942 | + throw new InvalidOperationException( |
| 1943 | + $"Firestore named-database selectors should not throw after the missing bindings are added, but observed {ex.GetType().FullName}. " + |
| 1944 | + $"Selectors exercised: '{firestoreForDatabaseSelector}', '{firestoreForAppDatabaseSelector}'. " + |
| 1945 | + $"Database id: {databaseId}. " + |
| 1946 | + $"NSException.Name: {FormatDetail(marshaledException?.Name?.ToString())}. " + |
| 1947 | + $"NSException.Reason: {FormatDetail(marshaledException?.Reason)}. " + |
| 1948 | + $"Marshal mode: {FormatDetail(marshaledExceptionMode?.ToString())}.", |
| 1949 | + ex); |
| 1950 | + } |
| 1951 | + |
| 1952 | + if (defaultNamedDatabase is null) |
| 1953 | + { |
| 1954 | + throw new InvalidOperationException($"Selector '{firestoreForDatabaseSelector}' returned null."); |
| 1955 | + } |
| 1956 | + |
| 1957 | + if (appNamedDatabase is null) |
| 1958 | + { |
| 1959 | + throw new InvalidOperationException($"Selector '{firestoreForAppDatabaseSelector}' returned null."); |
| 1960 | + } |
| 1961 | + |
| 1962 | + var defaultCollection = defaultNamedDatabase.GetCollection($"codex-named-database-default-{Guid.NewGuid():N}"); |
| 1963 | + if (defaultCollection is null) |
| 1964 | + { |
| 1965 | + throw new InvalidOperationException( |
| 1966 | + $"Firestore instance from selector '{firestoreForDatabaseSelector}' could not create a collection reference."); |
| 1967 | + } |
| 1968 | + |
| 1969 | + var appCollection = appNamedDatabase.GetCollection($"codex-named-database-app-{Guid.NewGuid():N}"); |
| 1970 | + if (appCollection is null) |
| 1971 | + { |
| 1972 | + throw new InvalidOperationException( |
| 1973 | + $"Firestore instance from selector '{firestoreForAppDatabaseSelector}' could not create a collection reference."); |
| 1974 | + } |
| 1975 | + |
| 1976 | + if (marshaledException is not null) |
| 1977 | + { |
| 1978 | + throw new InvalidOperationException( |
| 1979 | + $"Firestore named-database selectors completed, but Runtime.MarshalObjectiveCException captured unexpected NSException.Name '{marshaledException.Name}'. " + |
| 1980 | + $"Reason: {FormatDetail(marshaledException.Reason)}. Marshal mode: {FormatDetail(marshaledExceptionMode?.ToString())}."); |
| 1981 | + } |
| 1982 | + |
| 1983 | + return Task.FromResult( |
| 1984 | + $"Firestore named-database factory APIs crossed the native selector boundary. " + |
| 1985 | + $"Database id: {databaseId}. " + |
| 1986 | + $"Default-app selector returned: {defaultNamedDatabase.GetType().FullName}. " + |
| 1987 | + $"Explicit-app selector returned: {appNamedDatabase.GetType().FullName}. " + |
| 1988 | + $"Collection references: {defaultCollection.Path}, {appCollection.Path}."); |
| 1989 | + } |
| 1990 | + finally |
| 1991 | + { |
| 1992 | + Runtime.MarshalObjectiveCException -= OnMarshalObjectiveCException; |
| 1993 | + } |
| 1994 | + } |
| 1995 | +#endif |
| 1996 | + |
1878 | 1997 | #if ENABLE_RUNTIME_DRIFT_CASE_CLOUDFUNCTIONS_USEFUNCTIONSEMULATORORIGIN |
1879 | 1998 | static Task<string> VerifyCloudFunctionsUseFunctionsEmulatorOriginAsync() |
1880 | 1999 | { |
|
0 commit comments