@@ -112,59 +112,149 @@ TEST(TimestampIsNear, Matcher) {
112112 EXPECT_THAT (firebase::Variant::EmptyString (), Not (TimestampIsNear (0 )));
113113}
114114
115+
115116class FirebaseDatabaseTest : public FirebaseTest {
116117 public:
117118 FirebaseDatabaseTest ();
118119 ~FirebaseDatabaseTest () override ;
119120
121+ // Called once before all tests.
122+ static void SetUpTestSuite ();
123+ // Called once after all tests.
124+ static void TearDownTestSuite ();
125+
126+ // Called at the start of each test.
120127 void SetUp () override ;
128+ // Called after each test.
121129 void TearDown () override ;
122130
123131 protected:
124- // Initialize Firebase App, Firebase Auth, and Firebase Database.
125- void Initialize ();
126- // Shut down Firebase Database, Firebase Auth, and Firebase App.
127- void Terminate ();
132+ // Initialize Firebase App and Firebase Auth.
133+ static void InitializeAppAndAuth ();
134+ // Shut down Firebase App and Firebase Auth.
135+ static void TerminateAppAndAuth ();
136+
128137 // Sign in an anonymous user.
129- void SignIn ();
138+ static void SignIn ();
130139 // Sign out the current user, if applicable.
131- void SignOut ();
140+ static void SignOut ();
141+
142+ // Initialize Firebase Database.
143+ void InitializeDatabase ();
144+ // Shut down Firebase Database.
145+ void TerminateDatabase ();
132146
133147 firebase::database::DatabaseReference CreateWorkingPath (
134148 bool suppress_cleanup = false );
135149
150+ static firebase::App* shared_app_;
151+ static firebase::auth::Auth* shared_auth_;
152+
136153 static bool first_time_;
137154
138155 bool initialized_;
139- firebase::auth::Auth* auth_;
140156 firebase::database::Database* database_;
141157
142158 std::vector<firebase::database::DatabaseReference> cleanup_paths_;
143159};
144160
161+ // Initialization flow looks like this:
162+ // - Once, before any tests run:
163+ // - SetUpTestSuite: Initialize App and Auth. Sign in.
164+ // - For each test:
165+ // - SetUp: Initialize Database.
166+ // - Run the test.
167+ // - TearDown: Shut down Database.
168+ // - Once, after all tests are finished:
169+ // - TearDownTestSuite: Sign out. Shut down Auth and App.
170+
171+ firebase::App* FirebaseDatabaseTest::shared_app_;
172+ firebase::auth::Auth* FirebaseDatabaseTest::shared_auth_;
173+
145174bool FirebaseDatabaseTest::first_time_ = true ;
146175
176+ void FirebaseDatabaseTest::SetUpTestSuite () {
177+ InitializeAppAndAuth ();
178+ }
179+
180+ void FirebaseDatabaseTest::InitializeAppAndAuth () {
181+ LogDebug (" Initialize Firebase App." );
182+
183+ FindFirebaseConfig (FIREBASE_CONFIG_STRING);
184+
185+ #if defined(__ANDROID__)
186+ shared_app_ = ::firebase::App::Create (app_framework::GetJniEnv (),
187+ app_framework::GetActivity ());
188+ #else
189+ shared_app_ = ::firebase::App::Create ();
190+ #endif // defined(__ANDROID__)
191+
192+ ASSERT_NE (shared_app_, nullptr );
193+
194+ LogDebug (" Initializing Auth." );
195+
196+ // Initialize Firebase Auth.
197+ ::firebase::ModuleInitializer initializer;
198+ initializer.Initialize (
199+ shared_app_, &shared_auth_, [](::firebase::App* app, void * target) {
200+ LogDebug (" Attempting to initialize Firebase Auth." );
201+ ::firebase::InitResult result;
202+ *reinterpret_cast <firebase::auth::Auth**>(target) =
203+ ::firebase::auth::Auth::GetAuth (app, &result);
204+ return result;
205+ });
206+
207+ WaitForCompletion (initializer.InitializeLastResult (), " InitializeAuth" );
208+
209+ ASSERT_EQ (initializer.InitializeLastResult ().error (), 0 )
210+ << initializer.InitializeLastResult ().error_message ();
211+
212+ LogDebug (" Successfully initialized Auth." );
213+
214+ ASSERT_NE (shared_auth_, nullptr );
215+
216+ // Sign in anonymously.
217+ SignIn ();
218+ }
219+
220+ void FirebaseDatabaseTest::TearDownTestSuite () {
221+ TerminateAppAndAuth ();
222+ }
223+
224+ void FirebaseDatabaseTest::TerminateAppAndAuth () {
225+ if (shared_auth_) {
226+ LogDebug (" Signing out." );
227+ SignOut ();
228+ LogDebug (" Shutdown Auth." );
229+ delete shared_auth_;
230+ shared_auth_ = nullptr ;
231+ }
232+ if (shared_app_) {
233+ LogDebug (" Shutdown App." );
234+ delete shared_app_;
235+ shared_app_ = nullptr ;
236+ }
237+ }
238+
147239FirebaseDatabaseTest::FirebaseDatabaseTest ()
148- : initialized_(false ), auth_( nullptr ), database_(nullptr ) {
240+ : initialized_(false ), database_(nullptr ) {
149241 FindFirebaseConfig (FIREBASE_CONFIG_STRING);
150242}
151243
152244FirebaseDatabaseTest::~FirebaseDatabaseTest () {
153245 // Must be cleaned up on exit.
154- assert (app_ == nullptr );
155- assert (auth_ == nullptr );
156246 assert (database_ == nullptr );
157247}
158248
159249void FirebaseDatabaseTest::SetUp () {
160250 FirebaseTest::SetUp ();
161- Initialize ();
251+ InitializeDatabase ();
162252}
163253
164254void FirebaseDatabaseTest::TearDown () {
165255 // Delete the shared path, if there is one.
166256 if (initialized_) {
167- if (!cleanup_paths_.empty () && database_ && app_ ) {
257+ if (!cleanup_paths_.empty () && database_ && shared_app_ ) {
168258 LogDebug (" Cleaning up..." );
169259 std::vector<firebase::Future<void >> cleanups;
170260 cleanups.reserve (cleanup_paths_.size ());
@@ -177,55 +267,30 @@ void FirebaseDatabaseTest::TearDown() {
177267 }
178268 cleanup_paths_.clear ();
179269 }
180-
181- SignOut ();
182- Terminate ();
183270 }
184-
271+ TerminateDatabase ();
185272 FirebaseTest::TearDown ();
186273}
187274
188- void FirebaseDatabaseTest::Initialize () {
189- if (initialized_) return ;
190-
191- InitializeApp ();
192-
193- LogDebug (" Initializing Firebase Auth and Firebase Database." );
194-
195- // 0th element has a reference to this object, the rest have the initializer
196- // targets.
197- void * initialize_targets[] = {&auth_, &database_};
275+ void FirebaseDatabaseTest::InitializeDatabase () {
276+ LogDebug (" Initializing Firebase Database." );
198277
199- const firebase::ModuleInitializer::InitializerFn initializers[] = {
200- [](::firebase::App* app, void * data) {
201- void ** targets = reinterpret_cast <void **>(data);
202- LogDebug (" Attempting to initialize Firebase Auth." );
203- ::firebase::InitResult result;
204- *reinterpret_cast <::firebase::auth::Auth**>(targets[0 ]) =
205- ::firebase::auth::Auth::GetAuth (app, &result);
206- return result;
207- },
208- [](::firebase::App* app, void * data) {
209- void ** targets = reinterpret_cast <void **>(data);
278+ ::firebase::ModuleInitializer initializer;
279+ initializer.Initialize (
280+ shared_app_, &database_, [](::firebase::App* app, void * target) {
210281 LogDebug (" Attempting to initialize Firebase Database." );
211282 ::firebase::InitResult result;
212- firebase::database::Database* database =
213- firebase::database::Database::GetInstance (app, &result);
214- *reinterpret_cast <::firebase::database::Database**>(targets[1 ]) =
215- database;
283+ *reinterpret_cast <firebase::database::Database**>(target) =
284+ firebase::database::Database::GetInstance (app, &result);
216285 return result;
217- }};
218-
219- ::firebase::ModuleInitializer initializer;
220- initializer.Initialize (app_, initialize_targets, initializers,
221- sizeof (initializers) / sizeof (initializers[0 ]));
286+ });
222287
223- WaitForCompletion (initializer.InitializeLastResult (), " Initialize " );
288+ WaitForCompletion (initializer.InitializeLastResult (), " InitializeDatabase " );
224289
225290 ASSERT_EQ (initializer.InitializeLastResult ().error (), 0 )
226291 << initializer.InitializeLastResult ().error_message ();
227292
228- LogDebug (" Successfully initialized Firebase Auth and Firebase Database." );
293+ LogDebug (" Successfully initialized Firebase Database." );
229294
230295 // The first time we initialize database, enable persistence on mobile.
231296 // We need to do this here because on iOS you can only enable persistence
@@ -238,31 +303,27 @@ void FirebaseDatabaseTest::Initialize() {
238303 initialized_ = true ;
239304}
240305
241- void FirebaseDatabaseTest::Terminate () {
306+ void FirebaseDatabaseTest::TerminateDatabase () {
242307 if (!initialized_) return ;
243308
244309 if (database_) {
245310 LogDebug (" Shutdown the Database library." );
246311 delete database_;
247312 database_ = nullptr ;
248313 }
249- if (auth_) {
250- LogDebug (" Shutdown the Auth library." );
251- delete auth_;
252- auth_ = nullptr ;
253- }
254-
255- TerminateApp ();
256-
257314 initialized_ = false ;
258315
259316 ProcessEvents (100 );
260317}
261318
262319void FirebaseDatabaseTest::SignIn () {
320+ if (shared_auth_->current_user () != nullptr ) {
321+ // Already signed in.
322+ return ;
323+ }
263324 LogDebug (" Signing in." );
264325 firebase::Future<firebase::auth::User*> sign_in_future =
265- auth_ ->SignInAnonymously ();
326+ shared_auth_ ->SignInAnonymously ();
266327 WaitForCompletion (sign_in_future, " SignInAnonymously" );
267328 if (sign_in_future.error () != 0 ) {
268329 FAIL () << " Ensure your application has the Anonymous sign-in provider "
@@ -272,22 +333,22 @@ void FirebaseDatabaseTest::SignIn() {
272333}
273334
274335void FirebaseDatabaseTest::SignOut () {
275- if (auth_ == nullptr ) {
336+ if (shared_auth_ == nullptr ) {
276337 // Auth is not set up.
277338 return ;
278339 }
279- if (auth_ ->current_user () == nullptr ) {
340+ if (shared_auth_ ->current_user () == nullptr ) {
280341 // Already signed out.
281342 return ;
282343 }
283344
284- auth_ ->SignOut ();
345+ shared_auth_ ->SignOut ();
285346
286347 // Wait for the sign-out to finish.
287- while (auth_ ->current_user () != nullptr ) {
348+ while (shared_auth_ ->current_user () != nullptr ) {
288349 if (ProcessEvents (100 )) break ;
289350 }
290- EXPECT_EQ (auth_ ->current_user (), nullptr );
351+ EXPECT_EQ (shared_auth_ ->current_user (), nullptr );
291352}
292353
293354firebase::database::DatabaseReference FirebaseDatabaseTest::CreateWorkingPath (
@@ -306,8 +367,7 @@ TEST_F(FirebaseDatabaseTest, TestInitializeAndTerminate) {
306367}
307368
308369TEST_F (FirebaseDatabaseTest, TestSignIn) {
309- SignIn ();
310- EXPECT_NE (auth_->current_user (), nullptr );
370+ EXPECT_NE (shared_auth_->current_user (), nullptr );
311371}
312372
313373TEST_F (FirebaseDatabaseTest, TestCreateWorkingPath) {
@@ -456,7 +516,7 @@ TEST_F(FirebaseDatabaseTest, TestReadingFromPersistanceWhileOffline) {
456516 // Shut down the realtime database and restart it, to make sure that
457517 // persistence persists across database object instances.
458518 delete database_;
459- database_ = ::firebase::database::Database::GetInstance (app_ );
519+ database_ = ::firebase::database::Database::GetInstance (shared_app_ );
460520
461521 // Offline mode. If persistence works, we should still be able to fetch
462522 // our value even though we're offline.
@@ -1090,15 +1150,20 @@ TEST_F(FirebaseDatabaseTest, TestInvalidatingReferencesWhenDeletingApp) {
10901150
10911151 // Deleting App should invalidate all the objects and Futures, same as
10921152 // deleting Database.
1093- delete app_ ;
1094- app_ = nullptr ;
1153+ delete shared_app_ ;
1154+ shared_app_ = nullptr ;
10951155
10961156 EXPECT_FALSE (ref.is_valid ());
10971157 EXPECT_FALSE (query.is_valid ());
10981158 EXPECT_FALSE (snapshot.is_valid ());
10991159 EXPECT_EQ (set_future.status (), firebase::kFutureStatusInvalid );
11001160 EXPECT_EQ (get_future.status (), firebase::kFutureStatusInvalid );
11011161 EXPECT_EQ (delete_future.status (), firebase::kFutureStatusInvalid );
1162+
1163+ // Fully shut down App and Auth so they can be reinitialized.
1164+ TerminateAppAndAuth ();
1165+ // Reinitialize App and Auth.
1166+ InitializeAppAndAuth ();
11021167}
11031168
11041169TEST_F (FirebaseDatabaseTest, TestInfoConnected) {
0 commit comments