From c203c1a43b7be84213806a6adce13fa716d4657c Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Thu, 14 Jan 2021 07:55:44 -0800 Subject: [PATCH] Initial GitHub Actions (#1) --- .clang-format | 9 + .github/workflows/check.yml | 53 ++++++ .github/workflows/google-utilities.yml | 71 ++++---- Gemfile | 8 + Gemfile.lock | 138 +++++++++++++++ GoogleUtilities.podspec | 35 ++-- .../Swizzler/GULAppDelegateSwizzlerTest.m | 160 ------------------ Mintfile | 1 + README.md | 6 +- .../URLSession/FIRURLSessionOCMockStub.h | 35 ++++ .../URLSession/FIRURLSessionOCMockStub.m | 65 +++++++ setup-scripts.sh | 22 +++ 12 files changed, 391 insertions(+), 212 deletions(-) create mode 100644 .clang-format create mode 100644 .github/workflows/check.yml create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Mintfile create mode 100644 SharedTestUtilities/URLSession/FIRURLSessionOCMockStub.h create mode 100644 SharedTestUtilities/URLSession/FIRURLSessionOCMockStub.m create mode 100755 setup-scripts.sh diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..4f53670 --- /dev/null +++ b/.clang-format @@ -0,0 +1,9 @@ +BasedOnStyle: Google +ColumnLimit: 100 +BinPackParameters: false +AllowAllParametersOfDeclarationOnNextLine: true +ObjCSpaceBeforeProtocolList: true +SpacesInContainerLiterals: true +PointerAlignment: Right +AllowShortFunctionsOnASingleLine: None +IncludeBlocks: Preserve diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..7ff802f --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,53 @@ +name: check + +on: + pull_request: + push: + branches: main + +jobs: + check: + runs-on: macos-latest + env: + MINT_PATH: ${{ github.workspace }}/mint + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-python@v2 + with: + python-version: 3.6 + + - name: Cache Mint packages + uses: actions/cache@v1 + with: + path: ${{ env.MINT_PATH }} + key: ${{ runner.os }}-mint-${{ hashFiles('**/Mintfile') }} + restore-keys: ${{ runner.os }}-mint- + + - name: Setup Scripts Directory + run: ./setup-scripts.sh + + - name: Setup check + run: | + brew update + brew install clang-format@11 + brew install mint + mint bootstrap + + - name: Style + run: scripts/style.sh test-only + + - name: Whitespace + run: scripts/check_whitespace.sh + + - name: Filename spaces + run: scripts/check_filename_spaces.sh + + - name: Copyrights + run: scripts/check_copyright.sh + + - name: Module imports + run: scripts/check_no_module_imports.sh + + - name: Imports + run: scripts/check_imports.swift diff --git a/.github/workflows/google-utilities.yml b/.github/workflows/google-utilities.yml index 0faaabb..d6249ff 100644 --- a/.github/workflows/google-utilities.yml +++ b/.github/workflows/google-utilities.yml @@ -2,25 +2,22 @@ name: google-utilities on: pull_request: - paths: - - 'GoogleUtilities**' - - '.github/workflows/google-utilities.yml' - - 'Gemfile' schedule: # Run every day at 11pm (PST) - cron uses UTC times - cron: '0 7 * * *' jobs: pod-lib-lint: - # Don't run on private repo unless it is a PR. - if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' - runs-on: macOS-latest strategy: matrix: target: [ios, tvos, macos] steps: - uses: actions/checkout@v2 + - name: ls + run: ls + - name: Setup Scripts Directory + run: ./setup-scripts.sh - name: Setup Bundler run: scripts/setup_bundler.sh - name: Build and test @@ -28,48 +25,46 @@ jobs: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb GoogleUtilities.podspec \ --platforms=${{ matrix.target }} - spm: - # Don't run on private repo unless it is a PR. - if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' - runs-on: macOS-latest - steps: - - uses: actions/checkout@v2 - - name: Initialize xcodebuild - run: xcodebuild -list - - name: iOS Unit Tests - # Only UserDefaults currently has a scheme. - run: scripts/third_party/travis/retry.sh ./scripts/build.sh GoogleUtilities_UserDefaults iOS spmbuildonly +# spm: +# runs-on: macOS-latest +# steps: +# - uses: actions/checkout@v2 +# - name: Setup Scripts Directory +# run: ./setup-scripts.sh +# - name: Initialize xcodebuild +# run: xcodebuild -list +# - name: iOS Unit Tests +# # Only UserDefaults currently has a scheme. +# run: scripts/third_party/travis/retry.sh ./scripts/build.sh GoogleUtilities_UserDefaults iOS spmbuildonly - spm-cron: - # Don't run on private repo. - if: github.event_name == 'schedule' && github.repository == 'Firebase/firebase-ios-sdk' - runs-on: macOS-latest - strategy: - matrix: - target: [tvOS, macOS, catalyst] - steps: - - uses: actions/checkout@v2 - - name: Initialize xcodebuild - run: xcodebuild -list - - name: Unit Tests - run: scripts/third_party/travis/retry.sh ./scripts/build.sh GoogleUtilities_UserDefaults ${{ matrix.target }} spmbuildonly +# spm-cron: +# # if: github.event_name == 'schedule' +# runs-on: macOS-latest +# strategy: +# matrix: +# target: [tvOS, macOS, catalyst] +# steps: +# - uses: actions/checkout@v2 +# - name: Setup Scripts Directory +# run: ./setup-scripts.sh +# - name: Initialize xcodebuild +# run: xcodebuild -list +# - name: Unit Tests +# run: scripts/third_party/travis/retry.sh ./scripts/build.sh GoogleUtilities_UserDefaults ${{ matrix.target }} spmbuildonly catalyst: - # Don't run on private repo unless it is a PR. - if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' - runs-on: macOS-latest steps: - uses: actions/checkout@v2 + - name: Setup Scripts Directory + run: ./setup-scripts.sh - name: Setup Bundler run: scripts/setup_bundler.sh - name: Setup project and Build for Catalyst run: scripts/test_catalyst.sh GoogleUtilities test GoogleUtilities-Unit-unit utilities-cron-only: - # Don't run on private repo. - if: github.event_name == 'schedule' && github.repository == 'Firebase/firebase-ios-sdk' - + if: github.event_name == 'schedule' runs-on: macos-latest strategy: matrix: @@ -81,6 +76,8 @@ jobs: needs: pod-lib-lint steps: - uses: actions/checkout@v2 + - name: Setup Scripts Directory + run: ./setup-scripts.sh - name: Setup Bundler run: scripts/setup_bundler.sh - name: PodLibLint GoogleUtilities Cron diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..c0e56b8 --- /dev/null +++ b/Gemfile @@ -0,0 +1,8 @@ +# To update, change version below, run bundle install, test, +# commit Gemfile and Gemfile.lock. +source 'https://rubygems.org' + +gem 'cocoapods', '1.10.1' + +gem 'cocoapods-generate', '2.0.1' +gem 'danger', '6.1.0' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..ac83864 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,138 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.3) + activesupport (5.2.4.4) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + atomos (0.1.3) + claide (1.0.3) + claide-plugins (0.9.2) + cork + nap + open4 (~> 1.3) + cocoapods (1.10.1) + addressable (~> 2.6) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.10.1) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 1.4.0, < 2.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.4.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.6.6) + nap (~> 1.0) + ruby-macho (~> 1.4) + xcodeproj (>= 1.19.0, < 2.0) + cocoapods-core (1.10.1) + activesupport (> 5.0, < 6) + addressable (~> 2.6) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + netrc (~> 0.11) + public_suffix + typhoeus (~> 1.0) + cocoapods-deintegrate (1.0.4) + cocoapods-disable-podfile-validations (0.1.1) + cocoapods-downloader (1.4.0) + cocoapods-generate (2.0.1) + cocoapods-disable-podfile-validations (~> 0.1.1) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.0) + cocoapods-trunk (1.5.0) + nap (>= 0.8, < 2.0) + netrc (~> 0.11) + cocoapods-try (1.2.0) + colored2 (3.1.2) + concurrent-ruby (1.1.7) + cork (0.3.0) + colored2 (~> 3.1) + danger (6.1.0) + claide (~> 1.0) + claide-plugins (>= 0.9.2) + colored2 (~> 3.1) + cork (~> 0.1) + faraday (~> 0.9) + faraday-http-cache (~> 2.0) + git (~> 1.5) + kramdown (~> 2.0) + kramdown-parser-gfm (~> 1.0) + no_proxy_fix + octokit (~> 4.7) + terminal-table (~> 1) + escape (0.0.4) + ethon (0.12.0) + ffi (>= 1.3.0) + faraday (0.17.0) + multipart-post (>= 1.2, < 3) + faraday-http-cache (2.0.0) + faraday (~> 0.8) + ffi (1.14.2) + fourflusher (2.3.1) + fuzzy_match (2.0.4) + gh_inspector (1.1.3) + git (1.5.0) + httpclient (2.8.3) + i18n (1.8.7) + concurrent-ruby (~> 1.0) + json (2.5.1) + kramdown (2.3.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + minitest (5.14.3) + molinillo (0.6.6) + multipart-post (2.1.1) + nanaimo (0.3.0) + nap (1.1.0) + netrc (0.11.0) + no_proxy_fix (0.1.2) + octokit (4.14.0) + sawyer (~> 0.8.0, >= 0.5.3) + open4 (1.3.4) + public_suffix (4.0.1) + rexml (3.2.4) + ruby-macho (1.4.0) + sawyer (0.8.2) + addressable (>= 2.3.5) + faraday (> 0.8, < 2.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thread_safe (0.3.6) + typhoeus (1.4.0) + ethon (>= 0.9.0) + tzinfo (1.2.9) + thread_safe (~> 0.1) + unicode-display_width (1.6.0) + xcodeproj (1.19.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.3.0) + +PLATFORMS + ruby + +DEPENDENCIES + cocoapods (= 1.10.1) + cocoapods-generate (= 2.0.1) + danger (= 6.1.0) + +BUNDLED WITH + 2.1.2 diff --git a/GoogleUtilities.podspec b/GoogleUtilities.podspec index 48012c6..321ee8d 100644 --- a/GoogleUtilities.podspec +++ b/GoogleUtilities.podspec @@ -1,26 +1,31 @@ Pod::Spec.new do |s| s.name = 'GoogleUtilities' s.version = '7.2.0' - s.summary = 'Google Utilities for iOS (plus community support for macOS and tvOS)' + s.summary = 'Google Utilities for Apple platform SDKs' s.description = <<-DESC Internal Google Utilities including Network, Reachability Environment, Logger and Swizzling for other Google CocoaPods. They're not intended for direct public usage. DESC - s.homepage = 'https://github.com/firebase/firebase-ios-sdk/tree/master/GoogleUtilities' - s.license = { :type => 'Apache', :file => 'GoogleUtilities/LICENSE' } + s.homepage = 'https://github.com/google/GoogleUtilities' + s.license = { :type => 'Apache', :file => 'LICENSE' } s.authors = 'Google, Inc.' s.source = { - :git => 'https://github.com/firebase/firebase-ios-sdk.git', - :tag => 'Utilities-' + s.version.to_s + :git => 'https://github.com/google/GoogleUtilities.git', + :tag => 'CocoaPods-' + s.version.to_s } - s.ios.deployment_target = '9.0' - s.osx.deployment_target = '10.12' - s.tvos.deployment_target = '10.0' - s.watchos.deployment_target = '6.0' + ios_deployment_target = '9.0' + osx_deployment_target = '10.12' + tvos_deployment_target = '10.0' + watchos_deployment_target = '6.0' + + s.ios.deployment_target = ios_deployment_target + s.osx.deployment_target = osx_deployment_target + s.tvos.deployment_target = tvos_deployment_target + s.watchos.deployment_target = watchos_deployment_target s.cocoapods_version = '>= 1.4.0' s.prefix_header_file = false @@ -118,7 +123,11 @@ other Google CocoaPods. They're not intended for direct public usage. s.test_spec 'unit' do |unit_tests| unit_tests.scheme = { :code_coverage => true } # All tests require arc except Tests/Network/third_party/GTMHTTPServer.m - unit_tests.platforms = {:ios => '8.0', :osx => '10.11', :tvos => '10.0'} + unit_tests.platforms = { + :ios => ios_deployment_target, + :osx => osx_deployment_target, + :tvos => tvos_deployment_target + } unit_tests.source_files = [ 'GoogleUtilities/Tests/Unit/**/*.[mh]', 'SharedTestUtilities/URLSession/*.[mh]', @@ -130,7 +139,11 @@ other Google CocoaPods. They're not intended for direct public usage. s.test_spec 'unit-swift' do |unit_tests_swift| unit_tests_swift.scheme = { :code_coverage => true } - unit_tests_swift.platforms = {:ios => '8.0', :osx => '10.11', :tvos => '10.0'} + unit_tests_swift.platforms = { + :ios => ios_deployment_target, + :osx => osx_deployment_target, + :tvos => tvos_deployment_target + } unit_tests_swift.source_files = 'GoogleUtilities/Tests/SwiftUnit/**/*.swift', 'GoogleUtilities/Tests/SwiftUnit/**/*.h' unit_tests_swift.requires_app_host = true diff --git a/GoogleUtilities/Tests/Unit/Swizzler/GULAppDelegateSwizzlerTest.m b/GoogleUtilities/Tests/Unit/Swizzler/GULAppDelegateSwizzlerTest.m index 74d6641..6c424e1 100644 --- a/GoogleUtilities/Tests/Unit/Swizzler/GULAppDelegateSwizzlerTest.m +++ b/GoogleUtilities/Tests/Unit/Swizzler/GULAppDelegateSwizzlerTest.m @@ -63,7 +63,6 @@ static NSString *const kGULGoogleAppDelegateProxyEnabledPlistKey = @property(nonatomic, strong) NSURL *url; @property(nonatomic, strong) NSDictionary *openURLOptions; @property(nonatomic, strong) NSString *openURLSourceApplication; -@property(nonatomic, strong) id openURLAnnotation; @property(nonatomic, strong) NSUserActivity *userActivity; @@ -88,13 +87,6 @@ static NSString *const kGULGoogleAppDelegateProxyEnabledPlistKey = // GULTestAppDelegate before GULAppDelegateSwizzlerTest. It works, but it might be a good idea to // figure a way to make this more deterministic. -/** YES if GULTestAppDelegate responds to application:openURL:sourceApplication:annotation:, NO - * otherwise. - */ -#if TARGET_OS_IOS || TARGET_OS_TV -static BOOL gRespondsToOpenURLHandler_iOS8; -#endif - /** YES if GULTestAppDelegate responds to application:openURL:options:, NO otherwise. */ static BOOL gRespondsToOpenURLHandler_iOS9; @@ -112,12 +104,6 @@ static BOOL gRespondsToHandleBackgroundSession; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - // Before being proxied, it should be only be able to respond to - // application:openURL:sourceApplication:annotation:. -#if TARGET_OS_IOS || TARGET_OS_TV - gRespondsToOpenURLHandler_iOS8 = [self - instancesRespondToSelector:@selector(application:openURL:sourceApplication:annotation:)]; -#endif gRespondsToOpenURLHandler_iOS9 = [self instancesRespondToSelector:@selector(application:openURL:options:)]; gRespondsToHandleBackgroundSession = @@ -150,19 +136,6 @@ static BOOL gRespondsToHandleBackgroundSession; return NO; } -#if TARGET_OS_IOS -- (BOOL)application:(GULApplication *)application - openURL:(NSURL *)url - sourceApplication:(NSString *)sourceApplication - annotation:(id)annotation { - self.application = application; - self.url = url; - self.openURLSourceApplication = sourceApplication; - self.openURLAnnotation = annotation; - return NO; -} -#endif // TARGET_OS_IOS - - (BOOL)application:(GULApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray> *__nullable @@ -239,9 +212,6 @@ static BOOL gRespondsToHandleBackgroundSession; /** URL sent to application:openURL:options:. */ @property(nonatomic, copy) NSURL *URLForIOS9; -/** URL sent to application:openURL:sourceApplication:annotation:. */ -@property(nonatomic, copy) NSURL *URLForIOS8; - /** The NSUserActivity sent to application:continueUserActivity:restorationHandler:. */ @property(nonatomic, copy) NSUserActivity *userActivity; @@ -256,16 +226,6 @@ static BOOL gRespondsToHandleBackgroundSession; return YES; } -#if TARGET_OS_IOS -- (BOOL)application:(GULApplication *)application - openURL:(nonnull NSURL *)url - sourceApplication:(nullable NSString *)sourceApplication - annotation:(nonnull id)annotation { - _URLForIOS8 = [url copy]; - return YES; -} -#endif // TARGET_OS_IOS - #if SDK_HAS_USERACTIVITY - (BOOL)application:(GULApplication *)application @@ -332,12 +292,6 @@ static BOOL gRespondsToHandleBackgroundSession; // Class size must stay the same. XCTAssertEqual(sizeBefore, sizeAfter); - // After being proxied, it should be able to respond to the required method selector. -#if TARGET_OS_IOS - XCTAssertTrue([realAppDelegate - respondsToSelector:@selector(application:openURL:sourceApplication:annotation:)]); -#endif // TARGET_OS_IOS - XCTAssertTrue([realAppDelegate respondsToSelector:@selector(application: continueUserActivity:restorationHandler:)]); XCTAssertTrue([realAppDelegate @@ -389,12 +343,6 @@ static BOOL gRespondsToHandleBackgroundSession; // Class size must stay the same. XCTAssertEqual(sizeBefore, sizeAfter); - // After being proxied, it should be able to respond to the required method selector. -#if TARGET_OS_IOS - XCTAssertTrue([realAppDelegate - respondsToSelector:@selector(application:openURL:sourceApplication:annotation:)]); -#endif // TARGET_OS_IOS - XCTAssertTrue([realAppDelegate respondsToSelector:@selector(application: continueUserActivity:restorationHandler:)]); // Remote notifications methods should be added only by @@ -442,12 +390,6 @@ static BOOL gRespondsToHandleBackgroundSession; // Class size must stay the same. XCTAssertEqual(sizeBefore, sizeAfter); - // After being proxied, it should be able to respond to the required method selector. -#if TARGET_OS_IOS - XCTAssertTrue([realAppDelegate - respondsToSelector:@selector(application:openURL:sourceApplication:annotation:)]); -#endif // TARGET_OS_IOS - XCTAssertTrue([realAppDelegate respondsToSelector:@selector(application: continueUserActivity:restorationHandler:)]); @@ -501,12 +443,6 @@ static BOOL gRespondsToHandleBackgroundSession; // Class size must stay the same. XCTAssertEqual(sizeBefore, sizeAfter); - // After being proxied, it should be able to respond to the required method selector. -#if TARGET_OS_IOS - XCTAssertTrue([realAppDelegate - respondsToSelector:@selector(application:openURL:sourceApplication:annotation:)]); -#endif // TARGET_OS_IOS - XCTAssertTrue([realAppDelegate respondsToSelector:@selector(application: continueUserActivity:restorationHandler:)]); // Proxy remote notifications methods @@ -753,102 +689,6 @@ static BOOL gRespondsToHandleBackgroundSession; } #endif // TARGET_OS_IOS || TARGET_OS_TV -#if TARGET_OS_IOS -/** Tests that application:openURL:sourceApplication:annotation: is invoked on the interceptors if - * it exists. - */ -- (void)testApplicationOpenURLSourceApplicationAnnotationIsInvokedOnInterceptors { - id interceptor = OCMProtocolMock(@protocol(GULApplicationDelegate)); - OCMExpect([interceptor application:OCMOCK_ANY - openURL:OCMOCK_ANY - sourceApplication:OCMOCK_ANY - annotation:OCMOCK_ANY]) - .andReturn(NO); - - id interceptor2 = OCMProtocolMock(@protocol(GULApplicationDelegate)); - OCMExpect([interceptor2 application:OCMOCK_ANY - openURL:OCMOCK_ANY - sourceApplication:OCMOCK_ANY - annotation:OCMOCK_ANY]) - .andReturn(NO); - - NSURL *testURL = [[NSURL alloc] initWithString:@"https://www.google.com"]; - - GULTestAppDelegate *testAppDelegate = [[GULTestAppDelegate alloc] init]; - OCMStub([self.mockSharedApplication delegate]).andReturn(testAppDelegate); - [GULAppDelegateSwizzler proxyOriginalDelegate]; - - [GULAppDelegateSwizzler registerAppDelegateInterceptor:interceptor]; - [GULAppDelegateSwizzler registerAppDelegateInterceptor:interceptor2]; - - NSString *sourceApplication = @"testApp"; - NSString *annotation = @"testAnnotation"; - [testAppDelegate application:[GULApplication sharedApplication] - openURL:testURL - sourceApplication:sourceApplication - annotation:annotation]; - - OCMVerifyAll(interceptor); - OCMVerifyAll(interceptor2); - - // Check that original implementation was called with proper parameters - XCTAssertEqual(testAppDelegate.application, [GULApplication sharedApplication]); - XCTAssertEqual(testAppDelegate.url, testURL); - XCTAssertEqual(testAppDelegate.openURLSourceApplication, sourceApplication); - XCTAssertEqual(testAppDelegate.openURLAnnotation, annotation); -} - -/** Tests that the result of application:openURL:sourceApplication:annotation: from all interceptors - * is ORed. - */ -- (void)testApplicationOpenURLSourceApplicationAnnotationResultIsORed { - GULTestAppDelegate *testAppDelegate = [[GULTestAppDelegate alloc] init]; - OCMStub([self.mockSharedApplication delegate]).andReturn(testAppDelegate); - NSURL *testURL = [[NSURL alloc] initWithString:@"https://www.google.com"]; - [GULAppDelegateSwizzler proxyOriginalDelegate]; - - BOOL shouldOpen = [testAppDelegate application:[GULApplication sharedApplication] - openURL:testURL - sourceApplication:@"test" - annotation:@"test"]; - // Verify that without interceptors the result is NO. - XCTAssertFalse(shouldOpen); - - id interceptor = OCMProtocolMock(@protocol(GULApplicationDelegate)); - OCMExpect([interceptor application:OCMOCK_ANY - openURL:OCMOCK_ANY - sourceApplication:OCMOCK_ANY - annotation:OCMOCK_ANY]) - .andReturn(NO); - [GULAppDelegateSwizzler registerAppDelegateInterceptor:interceptor]; - shouldOpen = [testAppDelegate application:[GULApplication sharedApplication] - openURL:testURL - sourceApplication:@"test" - annotation:@"test"]; - // The result is still NO if the only interceptor returns NO. - XCTAssertFalse(shouldOpen); - - id interceptor2 = OCMProtocolMock(@protocol(GULApplicationDelegate)); - OCMExpect([interceptor2 application:OCMOCK_ANY - openURL:OCMOCK_ANY - sourceApplication:OCMOCK_ANY - annotation:OCMOCK_ANY]) - .andReturn(YES); - OCMExpect([interceptor application:OCMOCK_ANY - openURL:OCMOCK_ANY - sourceApplication:OCMOCK_ANY - annotation:OCMOCK_ANY]) - .andReturn(NO); - [GULAppDelegateSwizzler registerAppDelegateInterceptor:interceptor2]; - shouldOpen = [testAppDelegate application:[GULApplication sharedApplication] - openURL:testURL - sourceApplication:@"test" - annotation:@"test"]; - // The result is YES if one of the interceptors returns YES. - XCTAssertTrue(shouldOpen); -} -#endif // TARGET_OS_IOS - #if TARGET_OS_IOS || TARGET_OS_TV /** Tests that application:handleEventsForBackgroundURLSession:completionHandler: is invoked on the * interceptors if it exists. diff --git a/Mintfile b/Mintfile new file mode 100644 index 0000000..30fa82e --- /dev/null +++ b/Mintfile @@ -0,0 +1 @@ +nicklockwood/SwiftFormat@0.45.5 diff --git a/README.md b/README.md index 45aa982..bf99308 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,7 @@ The utilities are not directly supported for non-Google library usage. ## Development -To develop Firebase software in this repository, ensure that you have at least -the following software: +To develop in this repository, ensure that you have at least the following software: * Xcode 12.0 (or later) * CocoaPods 1.10.0 (or later) @@ -66,8 +65,7 @@ Select a scheme and press Command-u to build a component and run its unit tests. ## Contributing -See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase -iOS SDK. +See [Contributing](CONTRIBUTING.md). ## License diff --git a/SharedTestUtilities/URLSession/FIRURLSessionOCMockStub.h b/SharedTestUtilities/URLSession/FIRURLSessionOCMockStub.h new file mode 100644 index 0000000..2895b03 --- /dev/null +++ b/SharedTestUtilities/URLSession/FIRURLSessionOCMockStub.h @@ -0,0 +1,35 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +typedef BOOL (^FIRRequestValidationBlock)(NSURLRequest *request); + +@interface FIRURLSessionOCMockStub : NSObject + ++ (id)stubURLSessionDataTaskWithResponse:(nullable NSHTTPURLResponse *)response + body:(nullable NSData *)body + error:(nullable NSError *)error + URLSessionMock:(id)URLSessionMock + requestValidationBlock:(nullable FIRRequestValidationBlock)requestValidationBlock; + ++ (NSHTTPURLResponse *)HTTPResponseWithCode:(NSInteger)statusCode; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SharedTestUtilities/URLSession/FIRURLSessionOCMockStub.m b/SharedTestUtilities/URLSession/FIRURLSessionOCMockStub.m new file mode 100644 index 0000000..2d0c9d8 --- /dev/null +++ b/SharedTestUtilities/URLSession/FIRURLSessionOCMockStub.m @@ -0,0 +1,65 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "SharedTestUtilities/URLSession/FIRURLSessionOCMockStub.h" + +#import "OCMock.h" + +@implementation FIRURLSessionOCMockStub + ++ (id)stubURLSessionDataTaskWithResponse:(NSHTTPURLResponse *)response + body:(NSData *)body + error:(NSError *)error + URLSessionMock:(id)URLSessionMock + requestValidationBlock:(FIRRequestValidationBlock)requestValidationBlock { + id mockDataTask = OCMStrictClassMock([NSURLSessionDataTask class]); + + // Validate request content. + FIRRequestValidationBlock nonOptionalRequestValidationBlock = + requestValidationBlock ?: ^BOOL(id request) { + return YES; + }; + + id URLRequestValidationArg = [OCMArg checkWithBlock:nonOptionalRequestValidationBlock]; + + // Save task completion to be called on the `[NSURLSessionDataTask resume]` + __block void (^taskCompletion)(NSData *, NSURLResponse *, NSError *); + id completionArg = [OCMArg checkWithBlock:^BOOL(id obj) { + taskCompletion = obj; + return YES; + }]; + + // Expect `dataTaskWithRequest` to be called. + OCMExpect([URLSessionMock dataTaskWithRequest:URLRequestValidationArg + completionHandler:completionArg]) + .andReturn(mockDataTask); + + // Expect the task to be resumed and call the task completion. + OCMExpect([(NSURLSessionDataTask *)mockDataTask resume]).andDo(^(NSInvocation *invocation) { + taskCompletion(body, response, error); + }); + + return mockDataTask; +} + ++ (NSHTTPURLResponse *)HTTPResponseWithCode:(NSInteger)statusCode { + return [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:@"http://localhost"] + statusCode:statusCode + HTTPVersion:@"HTTP/1.1" + headerFields:nil]; +} + +@end diff --git a/setup-scripts.sh b/setup-scripts.sh new file mode 100755 index 0000000..423b82a --- /dev/null +++ b/setup-scripts.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Copyright 2021 Google LLC +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +git clone \ + --depth 1 \ + --no-checkout \ + https://github.com/firebase/firebase-ios-sdk.git \ +; +cd firebase-ios-sdk +git checkout master -- scripts +cd .. +ln -s firebase-ios-sdk/scripts scripts