Skip to content

Commit e9252d2

Browse files
mortenbekditlevsenpaulb777
authored andcommitted
Make Shared Firebase Codable from RTDB Codable
1 parent 5bba524 commit e9252d2

File tree

10 files changed

+580
-391
lines changed

10 files changed

+580
-391
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import FirebaseDatabase
18+
import FirebaseSharedSwift
19+
20+
extension Database {
21+
public typealias Encoder = StructureEncoder
22+
public typealias Decoder = StructureDecoder
23+
}

FirebaseDatabaseSwift/Tests/Codable/ServerValueCodingTests.swift

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,114 @@ extension CurrencyAmount: ExpressibleByFloatLiteral {
8787
self.value = Decimal(value)
8888
}
8989
}
90+
91+
private func assertThat(_ dictionary: [String: Any],
92+
file: StaticString = #file,
93+
line: UInt = #line) -> DictionarySubject {
94+
return DictionarySubject(dictionary, file: file, line: line)
95+
}
96+
97+
func assertThat<X: Equatable & Codable>(_ model: X, file: StaticString = #file,
98+
line: UInt = #line) -> CodableSubject<X> {
99+
return CodableSubject(model, file: file, line: line)
100+
}
101+
102+
func assertThat<X: Equatable & Encodable>(_ model: X, file: StaticString = #file,
103+
line: UInt = #line) -> EncodableSubject<X> {
104+
return EncodableSubject(model, file: file, line: line)
105+
}
106+
107+
class EncodableSubject<X: Equatable & Encodable> {
108+
var subject: X
109+
var file: StaticString
110+
var line: UInt
111+
112+
init(_ subject: X, file: StaticString, line: UInt) {
113+
self.subject = subject
114+
self.file = file
115+
self.line = line
116+
}
117+
118+
@discardableResult
119+
func encodes(to expected: [String: Any],
120+
using encoder: Database.Encoder = .init()) -> DictionarySubject {
121+
let encoded = assertEncodes(to: expected, using: encoder)
122+
return DictionarySubject(encoded, file: file, line: line)
123+
}
124+
125+
func failsToEncode() {
126+
do {
127+
let encoder = Database.Encoder()
128+
encoder.keyEncodingStrategy = .convertToSnakeCase
129+
_ = try encoder.encode(subject)
130+
} catch {
131+
return
132+
}
133+
XCTFail("Failed to throw")
134+
}
135+
136+
func failsEncodingAtTopLevel() {
137+
do {
138+
let encoder = Database.Encoder()
139+
encoder.keyEncodingStrategy = .convertToSnakeCase
140+
_ = try encoder.encode(subject)
141+
XCTFail("Failed to throw", file: file, line: line)
142+
} catch EncodingError.invalidValue(_, _) {
143+
return
144+
} catch {
145+
XCTFail("Unrecognized error: \(error)", file: file, line: line)
146+
}
147+
}
148+
149+
private func assertEncodes(to expected: [String: Any],
150+
using encoder: Database.Encoder = .init()) -> [String: Any] {
151+
do {
152+
let enc = try encoder.encode(subject)
153+
XCTAssertEqual(enc as? NSDictionary, expected as NSDictionary, file: file, line: line)
154+
return (enc as! NSDictionary) as! [String: Any]
155+
} catch {
156+
XCTFail("Failed to encode \(X.self): error: \(error)")
157+
return ["": -1]
158+
}
159+
}
160+
}
161+
162+
class CodableSubject<X: Equatable & Codable>: EncodableSubject<X> {
163+
func roundTrips(to expected: [String: Any],
164+
using encoder: Database.Encoder = .init(),
165+
decoder: Database.Decoder = .init()) {
166+
let reverseSubject = encodes(to: expected, using: encoder)
167+
reverseSubject.decodes(to: subject, using: decoder)
168+
}
169+
}
170+
171+
class DictionarySubject {
172+
var subject: [String: Any]
173+
var file: StaticString
174+
var line: UInt
175+
176+
init(_ subject: [String: Any], file: StaticString, line: UInt) {
177+
self.subject = subject
178+
self.file = file
179+
self.line = line
180+
}
181+
182+
func decodes<X: Equatable & Codable>(to expected: X,
183+
using decoder: Database.Decoder = .init()) -> Void {
184+
do {
185+
let decoded = try decoder.decode(X.self, from: subject)
186+
XCTAssertEqual(decoded, expected)
187+
} catch {
188+
XCTFail("Failed to decode \(X.self): \(error)", file: file, line: line)
189+
}
190+
}
191+
192+
func failsDecoding<X: Equatable & Codable>(to _: X.Type,
193+
using decoder: Database.Decoder = .init()) -> Void {
194+
XCTAssertThrowsError(
195+
try decoder.decode(X.self, from: subject),
196+
file: file,
197+
line: line
198+
)
199+
}
200+
}

FirebaseSharedSwift/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

0 commit comments

Comments
 (0)