Skip to content

Commit c9c0346

Browse files
Prototype of a module with Firestore fakes for testing dependent code in Swift (#7668)
* Firestore testing support prototype * SwiftPM target * Comments and formatting * Move FirebaseFirestoreTestingSupport.podspec to subfolder * Swift PM updated * Headers location and imports * Podspec version update * Brief readme * Swift PM FirestoreTestingSupportTests target added * Formatting * Move FirebaseFirestoreTestingSupport.podspec back to root * README updates * Cleanup podspec * README
1 parent 5063d9f commit c9c0346

8 files changed

Lines changed: 403 additions & 0 deletions

File tree

.swiftpm/xcode/xcshareddata/xcschemes/Firebase-Package.xcscheme

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,104 @@
734734
ReferencedContainer = "container:">
735735
</BuildableReference>
736736
</BuildActionEntry>
737+
<BuildActionEntry
738+
buildForTesting = "YES"
739+
buildForRunning = "YES"
740+
buildForProfiling = "YES"
741+
buildForArchiving = "YES"
742+
buildForAnalyzing = "YES">
743+
<BuildableReference
744+
BuildableIdentifier = "primary"
745+
BlueprintIdentifier = "FirebaseAuthCombineSwift-Beta"
746+
BuildableName = "FirebaseAuthCombineSwift-Beta"
747+
BlueprintName = "FirebaseAuthCombineSwift-Beta"
748+
ReferencedContainer = "container:">
749+
</BuildableReference>
750+
</BuildActionEntry>
751+
<BuildActionEntry
752+
buildForTesting = "YES"
753+
buildForRunning = "YES"
754+
buildForProfiling = "YES"
755+
buildForArchiving = "YES"
756+
buildForAnalyzing = "YES">
757+
<BuildableReference
758+
BuildableIdentifier = "primary"
759+
BlueprintIdentifier = "FirebaseCombineSwift-Beta"
760+
BuildableName = "FirebaseCombineSwift-Beta"
761+
BlueprintName = "FirebaseCombineSwift-Beta"
762+
ReferencedContainer = "container:">
763+
</BuildableReference>
764+
</BuildActionEntry>
765+
<BuildActionEntry
766+
buildForTesting = "YES"
767+
buildForRunning = "YES"
768+
buildForProfiling = "YES"
769+
buildForArchiving = "YES"
770+
buildForAnalyzing = "YES">
771+
<BuildableReference
772+
BuildableIdentifier = "primary"
773+
BlueprintIdentifier = "FirebaseFunctionsCombineSwift-Beta"
774+
BuildableName = "FirebaseFunctionsCombineSwift-Beta"
775+
BlueprintName = "FirebaseFunctionsCombineSwift-Beta"
776+
ReferencedContainer = "container:">
777+
</BuildableReference>
778+
</BuildActionEntry>
779+
<BuildActionEntry
780+
buildForTesting = "YES"
781+
buildForRunning = "YES"
782+
buildForProfiling = "YES"
783+
buildForArchiving = "YES"
784+
buildForAnalyzing = "YES">
785+
<BuildableReference
786+
BuildableIdentifier = "primary"
787+
BlueprintIdentifier = "FirebaseAuthCombineSwift"
788+
BuildableName = "FirebaseAuthCombineSwift"
789+
BlueprintName = "FirebaseAuthCombineSwift"
790+
ReferencedContainer = "container:">
791+
</BuildableReference>
792+
</BuildActionEntry>
793+
<BuildActionEntry
794+
buildForTesting = "YES"
795+
buildForRunning = "YES"
796+
buildForProfiling = "YES"
797+
buildForArchiving = "YES"
798+
buildForAnalyzing = "YES">
799+
<BuildableReference
800+
BuildableIdentifier = "primary"
801+
BlueprintIdentifier = "FirebaseCombineSwift"
802+
BuildableName = "FirebaseCombineSwift"
803+
BlueprintName = "FirebaseCombineSwift"
804+
ReferencedContainer = "container:">
805+
</BuildableReference>
806+
</BuildActionEntry>
807+
<BuildActionEntry
808+
buildForTesting = "YES"
809+
buildForRunning = "YES"
810+
buildForProfiling = "YES"
811+
buildForArchiving = "YES"
812+
buildForAnalyzing = "YES">
813+
<BuildableReference
814+
BuildableIdentifier = "primary"
815+
BlueprintIdentifier = "FirebaseFirestoreTestingSupport"
816+
BuildableName = "FirebaseFirestoreTestingSupport"
817+
BlueprintName = "FirebaseFirestoreTestingSupport"
818+
ReferencedContainer = "container:">
819+
</BuildableReference>
820+
</BuildActionEntry>
821+
<BuildActionEntry
822+
buildForTesting = "YES"
823+
buildForRunning = "YES"
824+
buildForProfiling = "YES"
825+
buildForArchiving = "YES"
826+
buildForAnalyzing = "YES">
827+
<BuildableReference
828+
BuildableIdentifier = "primary"
829+
BlueprintIdentifier = "FirebaseFunctionsCombineSwift"
830+
BuildableName = "FirebaseFunctionsCombineSwift"
831+
BlueprintName = "FirebaseFunctionsCombineSwift"
832+
ReferencedContainer = "container:">
833+
</BuildableReference>
834+
</BuildActionEntry>
737835
</BuildActionEntries>
738836
</BuildAction>
739837
<TestAction
@@ -922,6 +1020,16 @@
9221020
ReferencedContainer = "container:">
9231021
</BuildableReference>
9241022
</TestableReference>
1023+
<TestableReference
1024+
skipped = "NO">
1025+
<BuildableReference
1026+
BuildableIdentifier = "primary"
1027+
BlueprintIdentifier = "FirestoreTestingSupportTests"
1028+
BuildableName = "FirestoreTestingSupportTests"
1029+
BlueprintName = "FirestoreTestingSupportTests"
1030+
ReferencedContainer = "container:">
1031+
</BuildableReference>
1032+
</TestableReference>
9251033
</Testables>
9261034
</TestAction>
9271035
<LaunchAction
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1240"
4+
version = "1.3">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES">
8+
</BuildAction>
9+
<TestAction
10+
buildConfiguration = "Debug"
11+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
12+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
13+
shouldUseLaunchSchemeArgsEnv = "YES">
14+
<Testables>
15+
<TestableReference
16+
skipped = "NO">
17+
<BuildableReference
18+
BuildableIdentifier = "primary"
19+
BlueprintIdentifier = "FirestoreTestingSupportTests"
20+
BuildableName = "FirestoreTestingSupportTests"
21+
BlueprintName = "FirestoreTestingSupportTests"
22+
ReferencedContainer = "container:">
23+
</BuildableReference>
24+
</TestableReference>
25+
</Testables>
26+
</TestAction>
27+
<LaunchAction
28+
buildConfiguration = "Debug"
29+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
30+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
31+
launchStyle = "0"
32+
useCustomWorkingDirectory = "NO"
33+
ignoresPersistentStateOnLaunch = "NO"
34+
debugDocumentVersioning = "YES"
35+
debugServiceExtension = "internal"
36+
allowLocationSimulation = "YES">
37+
</LaunchAction>
38+
<ProfileAction
39+
buildConfiguration = "Release"
40+
shouldUseLaunchSchemeArgsEnv = "YES"
41+
savedToolIdentifier = ""
42+
useCustomWorkingDirectory = "NO"
43+
debugDocumentVersioning = "YES">
44+
</ProfileAction>
45+
<AnalyzeAction
46+
buildConfiguration = "Debug">
47+
</AnalyzeAction>
48+
<ArchiveAction
49+
buildConfiguration = "Release"
50+
revealArchiveInOrganizer = "YES">
51+
</ArchiveAction>
52+
</Scheme>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
Pod::Spec.new do |s|
2+
s.name = 'FirebaseFirestoreTestingSupport'
3+
s.version = '1.0.0'
4+
s.summary = 'Firebase SDKs testing support types and utilities.'
5+
6+
s.description = <<-DESC
7+
Type declarations and utilities needed for unit testing of the code dependent on Firebase SDKs
8+
DESC
9+
10+
s.homepage = 'https://developers.google.com/'
11+
s.license = { :type => 'Apache', :file => 'LICENSE' }
12+
s.authors = 'Google, Inc.'
13+
14+
s.source = {
15+
:git => 'https://github.com/Firebase/firebase-ios-sdk.git',
16+
:tag => 'CocoaPods-' + s.version.to_s
17+
}
18+
19+
ios_deployment_target = '10.0'
20+
osx_deployment_target = '10.12'
21+
tvos_deployment_target = '10.0'
22+
watchos_deployment_target = '6.0'
23+
24+
s.ios.deployment_target = ios_deployment_target
25+
s.osx.deployment_target = osx_deployment_target
26+
s.tvos.deployment_target = tvos_deployment_target
27+
s.watchos.deployment_target = watchos_deployment_target
28+
29+
s.cocoapods_version = '>= 1.4.0'
30+
s.prefix_header_file = false
31+
s.requires_arc = true
32+
33+
base_dir = 'FirebaseTestingSupport/Firestore/'
34+
35+
s.source_files = [
36+
base_dir + 'Sources/**/*.{m,mm,h}',
37+
'Firestore/Source/API/*\+Internal.h'
38+
]
39+
40+
s.public_header_files = base_dir + '**/*.h'
41+
42+
s.dependency 'FirebaseFirestore', '~> 7.7'
43+
44+
s.pod_target_xcconfig = {
45+
'GCC_C_LANGUAGE_STANDARD' => 'c99',
46+
'OTHER_CFLAGS' => '-fno-autolink',
47+
'HEADER_SEARCH_PATHS' =>
48+
'"${PODS_TARGET_SRCROOT}" '
49+
}
50+
51+
s.test_spec 'unit' do |unit_tests|
52+
unit_tests.scheme = { :code_coverage => true }
53+
unit_tests.platforms = {:ios => ios_deployment_target, :osx => osx_deployment_target, :tvos => tvos_deployment_target}
54+
unit_tests.source_files = [
55+
base_dir + 'Tests/**/*.swift'
56+
]
57+
end
58+
end
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#import "FirebaseTestingSupport/Firestore/Sources/Public/FirebaseFirestoreTestingSupport/FIRQueryFake.h"
16+
17+
#import "Firestore/Source/API/FIRQuery+Internal.h"
18+
19+
@implementation FIRQueryFake
20+
21+
- (instancetype)init {
22+
// The object is partially initialized. Make sure the methods used during testing are overridden.
23+
return self;
24+
}
25+
26+
- (void)getDocumentsWithCompletion:(FIRQuerySnapshotBlock)completion {
27+
if (self.getDocumentsHandler) {
28+
self.getDocumentsHandler(completion);
29+
}
30+
}
31+
32+
@end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#import <FirebaseFirestore/FIRQuery.h>
16+
17+
NS_ASSUME_NONNULL_BEGIN
18+
19+
typedef void (^FIRFirestoreGetDocumentsHandler)(FIRQuerySnapshotBlock completion);
20+
21+
/// A fake object to replace a real `Query` in tests.
22+
NS_SWIFT_NAME(QueryFake)
23+
@interface FIRQueryFake : FIRQuery
24+
25+
- (instancetype)init;
26+
27+
/// The block to be called each time when `getDocuments(completion:)` method is called.
28+
@property(nonatomic, nullable, copy) FIRFirestoreGetDocumentsHandler getDocumentsHandler;
29+
30+
// TODO: Implement other handlers as needed.
31+
32+
@end
33+
34+
NS_ASSUME_NONNULL_END
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import XCTest
16+
@testable import FirebaseFirestoreTestingSupport
17+
18+
class QueryFakeTests: XCTestCase {
19+
func testQueryFakeConstructor() throws {
20+
let fakeQuery = QueryFake()
21+
XCTAssertNotNil(fakeQuery)
22+
XCTAssertTrue(fakeQuery.isKind(of: Query.self))
23+
}
24+
25+
func testQueryFakeGetDocumentsHandler() {
26+
let fakeQuery = QueryFake()
27+
28+
let handlerExpectation = expectation(description: "Handler called")
29+
fakeQuery.getDocumentsHandler = { completion in
30+
handlerExpectation.fulfill()
31+
32+
completion(nil, nil)
33+
}
34+
35+
let completionExpectation = expectation(description: "Completion called")
36+
fakeQuery.getDocuments { snapshot, error in
37+
completionExpectation.fulfill()
38+
XCTAssertNil(snapshot)
39+
XCTAssertNil(error)
40+
}
41+
42+
wait(for: [handlerExpectation, completionExpectation], timeout: 0.5)
43+
}
44+
}

0 commit comments

Comments
 (0)