Index: content/browser/geolocation/geolocation_provider_unittest.cc |
diff --git a/content/browser/geolocation/geolocation_provider_unittest.cc b/content/browser/geolocation/geolocation_provider_unittest.cc |
index ca1e12229a85f61b04c89469598cf0efb3ba1816..9f141a8282bd907c9e7bacbd679d5e8c00e20e7e 100644 |
--- a/content/browser/geolocation/geolocation_provider_unittest.cc |
+++ b/content/browser/geolocation/geolocation_provider_unittest.cc |
@@ -2,215 +2,226 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "base/memory/singleton.h" |
+#include "base/basictypes.h" |
+#include "base/bind.h" |
+#include "base/bind_helpers.h" |
+#include "base/compiler_specific.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/message_loop.h" |
#include "base/synchronization/waitable_event.h" |
-#include "content/browser/geolocation/arbitrator_dependency_factories_for_test.h" |
+#include "base/time.h" |
+#include "content/browser/geolocation/arbitrator_dependency_factory.h" |
#include "content/browser/geolocation/fake_access_token_store.h" |
+#include "content/browser/geolocation/geolocation_observer.h" |
#include "content/browser/geolocation/geolocation_provider.h" |
#include "content/browser/geolocation/location_arbitrator.h" |
#include "content/browser/geolocation/mock_location_provider.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/test/test_browser_thread.h" |
#include "testing/gmock/include/gmock/gmock.h" |
#include "testing/gtest/include/gtest/gtest.h" |
-using content::AccessTokenStore; |
-using content::FakeAccessTokenStore; |
using content::Geoposition; |
using testing::_; |
using testing::DoAll; |
-using testing::DoDefault; |
using testing::Invoke; |
using testing::InvokeWithoutArgs; |
+using testing::MakeMatcher; |
+using testing::Matcher; |
+using testing::MatcherInterface; |
+using testing::MatchResultListener; |
namespace { |
+class NonSingletonGeolocationProvider : public GeolocationProvider { |
+ public: |
+ NonSingletonGeolocationProvider() {} |
-class GeolocationProviderTest : public testing::Test { |
- protected: |
- GeolocationProviderTest() |
- : provider_(new GeolocationProvider), |
- dependency_factory_( |
- new GeolocationArbitratorDependencyFactoryWithLocationProvider( |
- &NewAutoSuccessMockNetworkLocationProvider)) |
- { |
+ virtual ~NonSingletonGeolocationProvider() {} |
+}; |
+ |
+class StartStopMockLocationProvider : public MockLocationProvider { |
+ public: |
+ explicit StartStopMockLocationProvider() : MockLocationProvider(&instance_) { |
} |
- ~GeolocationProviderTest() { |
- DefaultSingletonTraits<GeolocationProvider>::Delete(provider_); |
+ virtual ~StartStopMockLocationProvider() { |
+ Die(); |
} |
- // testing::Test |
- virtual void SetUp() { |
- GeolocationArbitrator::SetDependencyFactoryForTest( |
- dependency_factory_.get()); |
+ MOCK_METHOD0(Die, void()); |
+}; |
+ |
+class TestingDependencyFactory |
+ : public DefaultGeolocationArbitratorDependencyFactory { |
+ public: |
+ TestingDependencyFactory(base::WaitableEvent* event) : event_(event) { |
} |
- // testing::Test |
- virtual void TearDown() { |
- provider_->Stop(); |
- GeolocationArbitrator::SetDependencyFactoryForTest(NULL); |
+ virtual content::AccessTokenStore* NewAccessTokenStore() OVERRIDE { |
+ content::FakeAccessTokenStore* store = new content::FakeAccessTokenStore(); |
+ EXPECT_CALL(*store, LoadAccessTokens(_)) |
+ .WillRepeatedly(DoAll( |
+ Invoke(store, |
+ &content::FakeAccessTokenStore::DefaultLoadAccessTokens), |
+ InvokeWithoutArgs(store, |
+ &content::FakeAccessTokenStore:: |
+ NotifyDelegateTokensLoaded), |
+ InvokeWithoutArgs(event_, &base::WaitableEvent::Signal))); |
+ return store; |
} |
- // Message loop for main thread, as provider depends on it existing. |
- MessageLoop message_loop_; |
+ virtual LocationProviderBase* NewNetworkLocationProvider( |
+ content::AccessTokenStore* access_token_store, |
+ net::URLRequestContextGetter* context, |
+ const GURL& url, |
+ const string16& access_token) OVERRIDE { |
+ StartStopMockLocationProvider* provider = |
+ new StartStopMockLocationProvider(); |
+ EXPECT_CALL(*provider, Die()) |
+ .Times(1) |
+ .WillOnce(InvokeWithoutArgs(event_, &base::WaitableEvent::Signal)); |
+ return provider; |
+ } |
- // Object under tests. Owned, but not a scoped_ptr due to specialized |
- // destruction protocol. |
- GeolocationProvider* provider_; |
+ virtual LocationProviderBase* NewSystemLocationProvider() OVERRIDE { |
+ return NULL; |
+ } |
- scoped_refptr<GeolocationArbitratorDependencyFactory> dependency_factory_; |
+ private: |
+ base::WaitableEvent* event_; |
}; |
-// Regression test for http://crbug.com/59377 |
-TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) { |
- EXPECT_FALSE(provider_->HasPermissionBeenGranted()); |
- provider_->OnPermissionGranted(); |
- EXPECT_TRUE(provider_->HasPermissionBeenGranted()); |
-} |
- |
class NullGeolocationObserver : public GeolocationObserver { |
public: |
// GeolocationObserver |
- virtual void OnLocationUpdate(const Geoposition& position) {} |
+ virtual void OnLocationUpdate(const content::Geoposition& position) {} |
}; |
class MockGeolocationObserver : public GeolocationObserver { |
public: |
// GeolocationObserver |
- MOCK_METHOD1(OnLocationUpdate, void(const Geoposition& position)); |
+ MOCK_METHOD1(OnLocationUpdate, void(const content::Geoposition& position)); |
}; |
-class StartStopMockLocationProvider : public MockLocationProvider { |
+class MockGeolocationCallbackWrapper { |
public: |
- explicit StartStopMockLocationProvider(MessageLoop* test_loop) |
- : MockLocationProvider(&instance_), |
- test_loop_(test_loop) { |
- } |
+ MOCK_METHOD1(Callback, void(const content::Geoposition& position)); |
+}; |
- virtual ~StartStopMockLocationProvider() { |
- Die(); |
+class GeopositionEqMatcher |
+ : public MatcherInterface<const content::Geoposition&> { |
+ public: |
+ explicit GeopositionEqMatcher(const content::Geoposition& expected) |
+ : expected_(expected) {} |
+ |
+ virtual bool MatchAndExplain(const content::Geoposition& actual, |
+ MatchResultListener* listener) const OVERRIDE { |
+ return actual.latitude == expected_.latitude && |
+ actual.longitude == expected_.longitude && |
+ actual.altitude == expected_.altitude && |
+ actual.accuracy == expected_.accuracy && |
+ actual.altitude_accuracy == expected_.altitude_accuracy && |
+ actual.heading == expected_.heading && |
+ actual.speed == expected_.speed && |
+ actual.timestamp == expected_.timestamp && |
+ actual.error_code == expected_.error_code && |
+ actual.error_message == expected_.error_message; |
} |
- MOCK_METHOD0(Die, void()); |
- |
- virtual bool StartProvider(bool high_accuracy) { |
- bool result = MockLocationProvider::StartProvider(high_accuracy); |
- test_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
- return result; |
+ virtual void DescribeTo(::std::ostream* os) const OVERRIDE { |
+ *os << "which matches the expected position"; |
} |
- virtual void StopProvider() { |
- MockLocationProvider::StopProvider(); |
- test_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
+ virtual void DescribeNegationTo(::std::ostream* os) const OVERRIDE{ |
+ *os << "which does not match the expected position"; |
} |
private: |
- MessageLoop* test_loop_; |
-}; |
- |
-class MockDependencyFactory : public GeolocationArbitratorDependencyFactory { |
- public: |
- MockDependencyFactory(MessageLoop* test_loop_, |
- AccessTokenStore* access_token_store) |
- : test_loop_(test_loop_), |
- access_token_store_(access_token_store) { |
- } |
+ content::Geoposition expected_; |
- virtual net::URLRequestContextGetter* GetContextGetter() { |
- return NULL; |
- } |
- |
- virtual GeolocationArbitrator::GetTimeNow GetTimeFunction() { |
- return base::Time::Now; |
- } |
+ DISALLOW_COPY_AND_ASSIGN(GeopositionEqMatcher); |
+}; |
- virtual AccessTokenStore* NewAccessTokenStore() { |
- return access_token_store_.get(); |
- } |
+Matcher<const content::Geoposition&> GeopositionEq( |
+ const content::Geoposition& expected) { |
+ return MakeMatcher(new GeopositionEqMatcher(expected)); |
+} |
- virtual LocationProviderBase* NewNetworkLocationProvider( |
- AccessTokenStore* access_token_store, |
- net::URLRequestContextGetter* context, |
- const GURL& url, |
- const string16& access_token) { |
- return new StartStopMockLocationProvider(test_loop_); |
+class GeolocationProviderTest : public testing::Test { |
+ protected: |
+ GeolocationProviderTest() |
+ : message_loop_(), |
+ io_thread_(content::BrowserThread::IO, &message_loop_), |
+ event_(false, false), |
+ dependency_factory_(new TestingDependencyFactory(&event_)), |
+ provider_(new NonSingletonGeolocationProvider) { |
+ GeolocationArbitrator::SetDependencyFactoryForTest( |
+ dependency_factory_.get()); |
} |
- virtual LocationProviderBase* NewSystemLocationProvider() { |
- return NULL; |
+ ~GeolocationProviderTest() { |
+ GeolocationArbitrator::SetDependencyFactoryForTest(NULL); |
} |
- private: |
- virtual ~MockDependencyFactory() {} |
+ MessageLoop message_loop_; |
+ content::TestBrowserThread io_thread_; |
- MessageLoop* test_loop_; |
- scoped_refptr<AccessTokenStore> access_token_store_; |
+ base::WaitableEvent event_; |
+ scoped_refptr<TestingDependencyFactory> dependency_factory_; |
+ scoped_ptr<NonSingletonGeolocationProvider> provider_; |
}; |
-TEST_F(GeolocationProviderTest, StartStop) { |
- scoped_refptr<FakeAccessTokenStore> fake_access_token_store = |
- new FakeAccessTokenStore; |
- scoped_refptr<GeolocationArbitratorDependencyFactory> dependency_factory = |
- new MockDependencyFactory(&message_loop_, fake_access_token_store.get()); |
- base::WaitableEvent event(false, false); |
- |
- EXPECT_CALL(*(fake_access_token_store.get()), LoadAccessTokens(_)) |
- .Times(1) |
- .WillOnce(DoAll(Invoke(fake_access_token_store.get(), |
- &FakeAccessTokenStore::DefaultLoadAccessTokens), |
- InvokeWithoutArgs(&event, &base::WaitableEvent::Signal))); |
- |
- GeolocationArbitrator::SetDependencyFactoryForTest(dependency_factory.get()); |
+// Regression test for http://crbug.com/59377 |
+TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) { |
+ EXPECT_FALSE(provider_->HasPermissionBeenGranted()); |
+ provider_->OnPermissionGranted(); |
+ EXPECT_TRUE(provider_->HasPermissionBeenGranted()); |
+} |
+TEST_F(GeolocationProviderTest, StartStop) { |
EXPECT_FALSE(provider_->IsRunning()); |
NullGeolocationObserver null_observer; |
GeolocationObserverOptions options; |
provider_->AddObserver(&null_observer, options); |
EXPECT_TRUE(provider_->IsRunning()); |
// Wait for token load request from the arbitrator to come through. |
- event.Wait(); |
- event.Reset(); |
- // The GeolocationArbitrator won't start the providers until it has |
- // finished loading access tokens. |
- fake_access_token_store->NotifyDelegateTokensLoaded(); |
- message_loop_.Run(); |
+ event_.Wait(); |
+ |
+ event_.Reset(); |
EXPECT_EQ(MockLocationProvider::instance_->state_, |
MockLocationProvider::LOW_ACCURACY); |
- EXPECT_CALL(*(static_cast<StartStopMockLocationProvider*>( |
- MockLocationProvider::instance_)), |
- Die()) |
- .Times(1) |
- .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal)); |
provider_->RemoveObserver(&null_observer); |
// Wait for the providers to be stopped. |
- event.Wait(); |
- event.Reset(); |
+ event_.Wait(); |
EXPECT_TRUE(provider_->IsRunning()); |
- |
- GeolocationArbitrator::SetDependencyFactoryForTest(NULL); |
} |
TEST_F(GeolocationProviderTest, OverrideLocationForTesting) { |
- scoped_refptr<FakeAccessTokenStore> fake_access_token_store = |
- new FakeAccessTokenStore; |
- scoped_refptr<GeolocationArbitratorDependencyFactory> dependency_factory = |
- new MockDependencyFactory(&message_loop_, fake_access_token_store.get()); |
+ content::Geoposition position; |
+ position.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; |
+ provider_->OverrideLocationForTesting(position); |
+ // Adding an observer when the location is overridden should synchronously |
+ // update the observer with our overridden position. |
MockGeolocationObserver mock_observer; |
- EXPECT_CALL(*(fake_access_token_store.get()), LoadAccessTokens(_)); |
- |
- GeolocationArbitrator::SetDependencyFactoryForTest(dependency_factory.get()); |
- |
- Geoposition override_position; |
- override_position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; |
- provider_->OverrideLocationForTesting(override_position); |
- // Adding an observer when the location is overriden should synchronously |
- // update the observer with our overriden position. |
- EXPECT_CALL(mock_observer, OnLocationUpdate( |
- testing::Field( |
- &Geoposition::error_code, |
- testing::Eq(Geoposition::ERROR_CODE_POSITION_UNAVAILABLE)))); |
+ EXPECT_CALL(mock_observer, OnLocationUpdate(GeopositionEq(position))); |
provider_->AddObserver(&mock_observer, GeolocationObserverOptions()); |
provider_->RemoveObserver(&mock_observer); |
+} |
- GeolocationArbitrator::SetDependencyFactoryForTest(NULL); |
+TEST_F(GeolocationProviderTest, Callback) { |
+ MockGeolocationCallbackWrapper callback_wrapper; |
+ provider_->RequestCallback( |
+ base::Bind(&MockGeolocationCallbackWrapper::Callback, |
+ base::Unretained(&callback_wrapper))); |
+ |
+ content::Geoposition position; |
+ position.latitude = 12; |
+ position.longitude = 34; |
+ position.accuracy = 56; |
+ position.timestamp = base::Time::Now(); |
+ EXPECT_CALL(callback_wrapper, Callback(GeopositionEq(position))); |
+ provider_->OverrideLocationForTesting(position); |
} |
} // namespace |