Skip to content

Commit b57f8b2

Browse files
authored
Add defer, a general facility for ad-hoc RAII. (#5554)
1 parent a3d8377 commit b57f8b2

File tree

9 files changed

+157
-13
lines changed

9 files changed

+157
-13
lines changed

Firestore/Example/Firestore.xcodeproj/project.pbxproj

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
1733601ECCEA33E730DEAF45 /* autoid_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54740A521FC913E500713A1A /* autoid_test.cc */; };
109109
17473086EBACB98CDC3CC65C /* view_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = C7429071B33BDF80A7FA2F8A /* view_test.cc */; };
110110
17638F813B9B556FE7718C0C /* FIRQuerySnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04F202154AA00B64F25 /* FIRQuerySnapshotTests.mm */; };
111+
17DC97DE15D200932174EC1F /* defer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8ABAC2E0402213D837F73DC3 /* defer_test.cc */; };
111112
17DFF30CF61D87883986E8B6 /* executor_std_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4687208F9B9100554BA2 /* executor_std_test.cc */; };
112113
1817DEF8FF479D218381C541 /* FSTGoogleTestTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 54764FAE1FAA21B90085E60A /* FSTGoogleTestTests.mm */; };
113114
18638EAED9E126FC5D895B14 /* common.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D221C2DDC800EFB9CC /* common.pb.cc */; };
@@ -168,6 +169,7 @@
168169
26777815544F549DD18D87AF /* message_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CE37875365497FFA8687B745 /* message_test.cc */; };
169170
268FC3360157A2DCAF89F92D /* snapshot_version_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABA495B9202B7E79008A7851 /* snapshot_version_test.cc */; };
170171
26B52236C9D049847042E1BD /* FSTMockDatastore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02D20213FFC00B64F25 /* FSTMockDatastore.mm */; };
172+
26C4E52128C8E7B5B96BECC4 /* defer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8ABAC2E0402213D837F73DC3 /* defer_test.cc */; };
171173
26C577D159CFFD73E24D543C /* memory_mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74FBEFA4FE4B12C435011763 /* memory_mutation_queue_test.cc */; };
172174
26CB3D7C871BC56456C6021E /* timestamp_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABF6506B201131F8005F2C74 /* timestamp_test.cc */; };
173175
276A563D546698B6AAC20164 /* annotations.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9520B89AAC00B5BCE7 /* annotations.pb.cc */; };
@@ -502,6 +504,7 @@
502504
5DDEC1A08F13226271FE636E /* resource_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2B02024FFD70028D6BE /* resource_path_test.cc */; };
503505
5E5B3B8B3A41C8EB70035A6B /* FSTTransactionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E07B202154EB00B64F25 /* FSTTransactionTests.mm */; };
504506
5E6F9184B271F6D5312412FF /* mutation_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = C8522DE226C467C54E6788D8 /* mutation_test.cc */; };
507+
5E7812753D960FBB373435BD /* defer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8ABAC2E0402213D837F73DC3 /* defer_test.cc */; };
505508
5E89B1A5A5430713C79C4854 /* FirestoreEncoderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1235769422B86E65007DDFA9 /* FirestoreEncoderTests.swift */; };
506509
5ECE040F87E9FCD0A5D215DB /* pretty_printing_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB323F9553050F4F6490F9FF /* pretty_printing_test.cc */; };
507510
5EE21E86159A1911E9503BC1 /* transform_operation_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 33607A3AE91548BD219EC9C6 /* transform_operation_test.cc */; };
@@ -547,6 +550,7 @@
547550
62DA31B79FE97A90EEF28B0B /* delayed_constructor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D0A6E9136804A41CEC9D55D4 /* delayed_constructor_test.cc */; };
548551
62F86BBE7DDA5B295B57C8DA /* string_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0EE5300F8233D14025EF0456 /* string_apple_test.mm */; };
549552
6300709ECDE8E0B5A8645F8D /* time_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5497CB76229DECDE000FB92F /* time_testing.cc */; };
553+
6325D0E43A402BC5866C9C0E /* defer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8ABAC2E0402213D837F73DC3 /* defer_test.cc */; };
550554
6359EA7D5C76D462BD31B5E5 /* watch_change_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2D7472BC70C024D736FF74D9 /* watch_change_test.cc */; };
551555
6369DE4E258556FE3382DD78 /* field_filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = E8551D6C6FB0B1BACE9E5BAD /* field_filter_test.cc */; };
552556
6380CACCF96A9B26900983DC /* leveldb_target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = E76F0CDF28E5FA62D21DE648 /* leveldb_target_cache_test.cc */; };
@@ -736,6 +740,7 @@
736740
95ED06D2B0078D3CDB821B68 /* FIRArrayTransformTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 73866A9F2082B069009BB4FF /* FIRArrayTransformTests.mm */; };
737741
9617B75E9E27E7BA46D87EF3 /* query_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B9C261C26C5D311E1E3C0CB9 /* query_test.cc */; };
738742
96552D8E218F68DDCFE210A0 /* status_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5493A423225F9990006DE7BA /* status_apple_test.mm */; };
743+
96898170B456EAF092F73BBC /* defer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8ABAC2E0402213D837F73DC3 /* defer_test.cc */; };
739744
974FF09E6AFD24D5A39B898B /* local_serializer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F8043813A5D16963EC02B182 /* local_serializer_test.cc */; };
740745
97729B53698C0E52EB165003 /* field_filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = E8551D6C6FB0B1BACE9E5BAD /* field_filter_test.cc */; };
741746
9774A6C2AA02A12D80B34C3C /* database_id_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB71064B201FA60300344F18 /* database_id_test.cc */; };
@@ -784,6 +789,7 @@
784789
A61BB461F3E5822175F81719 /* memory_remote_document_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1CA9800A53669EFBFFB824E3 /* memory_remote_document_cache_test.cc */; };
785790
A62CDCEBE56E37FBB085CFF9 /* fake_credentials_provider.cc in Sources */ = {isa = PBXBuildFile; fileRef = DCC17AF218430D8BB28DD197 /* fake_credentials_provider.cc */; };
786791
A6A916A7DEA41EE29FD13508 /* watch_change_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2D7472BC70C024D736FF74D9 /* watch_change_test.cc */; };
792+
A6A9946A006AA87240B37E31 /* defer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8ABAC2E0402213D837F73DC3 /* defer_test.cc */; };
787793
A6D57EC3A0BF39060705ED29 /* string_format_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CFD366B783AE27B9E79EE7A /* string_format_apple_test.mm */; };
788794
A6E236CE8B3A47BE32254436 /* array_sorted_map_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54EB764C202277B30088B8F3 /* array_sorted_map_test.cc */; };
789795
A7309DAD4A3B5334536ECA46 /* remote_event_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 584AE2C37A55B408541A6FF3 /* remote_event_test.cc */; };
@@ -1427,6 +1433,7 @@
14271433
87553338E42B8ECA05BA987E /* grpc_stream_tester.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = grpc_stream_tester.cc; sourceTree = "<group>"; };
14281434
88CF09277CFA45EE1273E3BA /* leveldb_transaction_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_transaction_test.cc; sourceTree = "<group>"; };
14291435
8A41BBE832158C76BE901BC9 /* mutation_queue_test.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = mutation_queue_test.h; sourceTree = "<group>"; };
1436+
8ABAC2E0402213D837F73DC3 /* defer_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; path = defer_test.cc; sourceTree = "<group>"; };
14301437
8C058C8BE2723D9A53CCD64B /* persistence_testing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = persistence_testing.h; sourceTree = "<group>"; };
14311438
8E002F4AD5D9B6197C940847 /* Firestore.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Firestore.podspec; path = ../Firestore.podspec; sourceTree = "<group>"; };
14321439
9098A0C535096F2EE9C35DE0 /* create_noop_connectivity_monitor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = create_noop_connectivity_monitor.h; sourceTree = "<group>"; };
@@ -1743,6 +1750,7 @@
17431750
54740A521FC913E500713A1A /* autoid_test.cc */,
17441751
AB380D01201BC69F00D97691 /* bits_test.cc */,
17451752
548DB928200D59F600E00ABC /* comparison_test.cc */,
1753+
8ABAC2E0402213D837F73DC3 /* defer_test.cc */,
17461754
D0A6E9136804A41CEC9D55D4 /* delayed_constructor_test.cc */,
17471755
B6FB4689208F9B9100554BA2 /* executor_libdispatch_test.mm */,
17481756
B6FB4687208F9B9100554BA2 /* executor_std_test.cc */,
@@ -3314,6 +3322,7 @@
33143322
9774A6C2AA02A12D80B34C3C /* database_id_test.cc in Sources */,
33153323
11F8EE69182C9699E90A9E3D /* database_info_test.cc in Sources */,
33163324
E2B7AEDCAAC5AD74C12E85C1 /* datastore_test.cc in Sources */,
3325+
5E7812753D960FBB373435BD /* defer_test.cc in Sources */,
33173326
62DA31B79FE97A90EEF28B0B /* delayed_constructor_test.cc in Sources */,
33183327
FF4FA5757D13A2B7CEE40F04 /* document.pb.cc in Sources */,
33193328
5B62003FEA9A3818FDF4E2DD /* document_key_test.cc in Sources */,
@@ -3488,6 +3497,7 @@
34883497
58E377DCCC64FE7D2C6B59A1 /* database_id_test.cc in Sources */,
34893498
8F3AE423677A4C50F7E0E5C0 /* database_info_test.cc in Sources */,
34903499
9A7CF567C6FF0623EB4CFF64 /* datastore_test.cc in Sources */,
3500+
17DC97DE15D200932174EC1F /* defer_test.cc in Sources */,
34913501
D22B96C19A0F3DE998D4320C /* delayed_constructor_test.cc in Sources */,
34923502
25A75DFA730BAD21A5538EC5 /* document.pb.cc in Sources */,
34933503
D6E0E54CD1640E726900828A /* document_key_test.cc in Sources */,
@@ -3673,6 +3683,7 @@
36733683
1465E362F7BA7A3D063E61C7 /* database_id_test.cc in Sources */,
36743684
A8AF92A35DFA30EEF9C27FB7 /* database_info_test.cc in Sources */,
36753685
B99452AB7E16B72D1C01FBBC /* datastore_test.cc in Sources */,
3686+
6325D0E43A402BC5866C9C0E /* defer_test.cc in Sources */,
36763687
2ABA80088D70E7A58F95F7D8 /* delayed_constructor_test.cc in Sources */,
36773688
1F38FD2703C58DFA69101183 /* document.pb.cc in Sources */,
36783689
BB1A6F7D8F06E74FB6E525C5 /* document_key_test.cc in Sources */,
@@ -3858,6 +3869,7 @@
38583869
1D618761796DE311A1707AA2 /* database_id_test.cc in Sources */,
38593870
E8495A8D1E11C0844339CCA3 /* database_info_test.cc in Sources */,
38603871
7B74447D211586D9D1CC82BB /* datastore_test.cc in Sources */,
3872+
A6A9946A006AA87240B37E31 /* defer_test.cc in Sources */,
38613873
4EE1ABA574FBFDC95165624C /* delayed_constructor_test.cc in Sources */,
38623874
E27C0996AF6EC6D08D91B253 /* document.pb.cc in Sources */,
38633875
B3F3DCA51819F1A213E00D9C /* document_key_test.cc in Sources */,
@@ -4042,6 +4054,7 @@
40424054
ABE6637A201FA81900ED349A /* database_id_test.cc in Sources */,
40434055
AB38D93020236E21000A432D /* database_info_test.cc in Sources */,
40444056
D3B470C98ACFAB7307FB3800 /* datastore_test.cc in Sources */,
4057+
26C4E52128C8E7B5B96BECC4 /* defer_test.cc in Sources */,
40454058
6EC28BB8C38E3FD126F68211 /* delayed_constructor_test.cc in Sources */,
40464059
544129DD21C2DDC800EFB9CC /* document.pb.cc in Sources */,
40474060
B6152AD7202A53CB000E5744 /* document_key_test.cc in Sources */,
@@ -4246,6 +4259,7 @@
42464259
61976CE9C088131EC564A503 /* database_id_test.cc in Sources */,
42474260
65FC1A102890C02EF1A65213 /* database_info_test.cc in Sources */,
42484261
4D6761FB02F4D915E466A985 /* datastore_test.cc in Sources */,
4262+
96898170B456EAF092F73BBC /* defer_test.cc in Sources */,
42494263
C663A8B74B57FD84717DEA21 /* delayed_constructor_test.cc in Sources */,
42504264
C426C6E424FB2199F5C2C5BC /* document.pb.cc in Sources */,
42514265
93E5620E3884A431A14500B0 /* document_key_test.cc in Sources */,

Firestore/core/src/util/defer.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2020 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+
#ifndef FIRESTORE_CORE_SRC_UTIL_DEFER_H_
18+
#define FIRESTORE_CORE_SRC_UTIL_DEFER_H_
19+
20+
#include <functional>
21+
#include <utility>
22+
23+
namespace firebase {
24+
namespace firestore {
25+
namespace util {
26+
27+
/**
28+
* Creates a deferred action object that will execute the given `action` when
29+
* the `Defer` object is destroyed at the close of the lexical scope containing
30+
* it. You must declare a local variable of type `Defer` for it to have any
31+
* useful effect; otherwise the `Defer` is destroyed at the end of the
32+
* statement, which is equivalent to just directly running the `action`.
33+
*
34+
* `Defer` is useful for performing ad-hoc RAII-style actions, without having
35+
* to create the wrapper class. For example:
36+
*
37+
* FILE* file = fopen(filename, "rb");
38+
* Defer cleanup([&] {
39+
* if (file) {
40+
* fclose(file);
41+
* }
42+
* });
43+
*/
44+
class Defer {
45+
// TODO(C++17): Make Action a template argument and use CTAD in the callers.
46+
public:
47+
using Action = std::function<void()>;
48+
49+
/**
50+
* Constructs a `Defer` object.
51+
*
52+
* @param action a callable object; usually a lambda. Even if exceptions are
53+
* enabled, when `action` is invoked it must not throw. This is similar
54+
* to the restriction that exists on destructors generally.
55+
*/
56+
explicit Defer(Action&& action) : action_(std::move(action)) {
57+
}
58+
59+
~Defer() {
60+
action_();
61+
}
62+
63+
// Defer can be neither copied nor moved.
64+
Defer(const Defer&) = delete;
65+
Defer& operator=(const Defer&) = delete;
66+
67+
private:
68+
Action action_;
69+
};
70+
71+
} // namespace util
72+
} // namespace firestore
73+
} // namespace firebase
74+
75+
#endif // FIRESTORE_CORE_SRC_UTIL_DEFER_H_

Firestore/core/src/util/filesystem_posix.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018 Google
2+
* Copyright 2018 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -168,7 +168,7 @@ Status Filesystem::IsDirectory(const Path& path) {
168168

169169
StatusOr<int64_t> Filesystem::FileSize(const Path& path) {
170170
struct stat st {};
171-
if (stat(path.c_str(), &st) == 0) {
171+
if (::stat(path.c_str(), &st) == 0) {
172172
return st.st_size;
173173
} else {
174174
return Status::FromErrno(

Firestore/core/src/util/filesystem_win.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018 Google
2+
* Copyright 2018 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
2424
#include <cerrno>
2525
#include <string>
2626

27+
#include "Firestore/core/src/util/defer.h"
2728
#include "Firestore/core/src/util/hard_assert.h"
2829
#include "Firestore/core/src/util/path.h"
2930
#include "Firestore/core/src/util/statusor.h"
@@ -36,16 +37,16 @@ namespace util {
3637

3738
StatusOr<Path> Filesystem::AppDataDir(absl::string_view app_name) {
3839
wchar_t* path = nullptr;
40+
auto cleanup = defer([&] { CoTaskMemFree(path); });
41+
3942
HRESULT hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &path);
4043
if (FAILED(hr)) {
41-
CoTaskMemFree(path);
4244
return Status::FromLastError(
4345
HRESULT_CODE(hr),
4446
"Failed to find the local application data directory");
4547
}
4648

4749
Path result = Path::FromUtf16(path, wcslen(path)).AppendUtf8(app_name);
48-
CoTaskMemFree(path);
4950
return std::move(result);
5051
}
5152

Firestore/core/src/util/string_apple.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018 Google
2+
* Copyright 2018 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -46,6 +46,15 @@ inline CFStringRef MakeCFString(absl::string_view contents) {
4646
kCFStringEncodingUTF8, false);
4747
}
4848

49+
/**
50+
* CFRelease that safely ignores null values.
51+
*/
52+
inline void SafeCFRelease(CFTypeRef cf) {
53+
if (cf) {
54+
CFRelease(cf);
55+
}
56+
}
57+
4958
#if defined(__OBJC__)
5059

5160
// Translates a string_view string to the equivalent NSString by making a copy.

Firestore/core/test/unit/model/field_value_test.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018 Google
2+
* Copyright 2018 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,6 +28,8 @@
2828
#include "Firestore/core/src/model/field_mask.h"
2929
#include "Firestore/core/src/model/field_path.h"
3030
#include "Firestore/core/src/nanopb/byte_string.h"
31+
#include "Firestore/core/src/util/defer.h"
32+
#include "Firestore/core/src/util/string_apple.h"
3133
#include "Firestore/core/test/unit/testutil/equals_tester.h"
3234
#include "Firestore/core/test/unit/testutil/testutil.h"
3335
#include "Firestore/core/test/unit/testutil/time_testing.h"
@@ -312,10 +314,10 @@ TEST_F(FieldValueTest, Equality) {
312314
TEST_F(FieldValueTest, CanonicalBitsAreCanonical) {
313315
double input = ToDouble(kAlternateNanBits);
314316
CFNumberRef number = CFNumberCreate(nullptr, kCFNumberDoubleType, &input);
317+
util::Defer cleanup([&] { util::SafeCFRelease(number); });
315318

316319
double actual = 0.0;
317320
CFNumberGetValue(number, kCFNumberDoubleType, &actual);
318-
CFRelease(number);
319321

320322
ASSERT_EQ(kCanonicalNanBits, ToBits(actual));
321323
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2020 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+
#include "Firestore/core/src/util/defer.h"
18+
19+
#include "gtest/gtest.h"
20+
21+
namespace firebase {
22+
namespace firestore {
23+
namespace util {
24+
25+
TEST(DeferTest, Defers) {
26+
int value = 0;
27+
{
28+
Defer cleanup([&] { ++value; });
29+
ASSERT_EQ(value, 0);
30+
}
31+
32+
ASSERT_EQ(value, 1);
33+
}
34+
35+
} // namespace util
36+
} // namespace firestore
37+
} // namespace firebase

Firestore/core/test/unit/util/filesystem_test.cc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018 Google
2+
* Copyright 2018 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
2222
#include <fstream>
2323

2424
#include "Firestore/core/src/util/autoid.h"
25+
#include "Firestore/core/src/util/defer.h"
2526
#include "Firestore/core/src/util/log.h"
2627
#include "Firestore/core/src/util/path.h"
2728
#include "Firestore/core/src/util/statusor.h"
@@ -43,9 +44,12 @@ using testutil::Touch;
4344
static void WriteStringToFile(const Path& path, const std::string& text) {
4445
std::ofstream out{path.native_value()};
4546
ASSERT_TRUE(out.good());
47+
Defer cleanup([&] {
48+
out.close();
49+
ASSERT_TRUE(out.good());
50+
});
51+
4652
out << text;
47-
out.close();
48-
ASSERT_TRUE(out.good());
4953
}
5054

5155
static void WriteBytesToFile(const Path& path, int byte_count) {

Firestore/core/test/unit/util/string_apple_test.mm

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018 Google
2+
* Copyright 2018 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
1919
#include <string>
2020
#include <vector>
2121

22+
#include "Firestore/core/src/util/defer.h"
2223
#include "gtest/gtest.h"
2324

2425
namespace firebase {
@@ -50,9 +51,10 @@
5051
TEST_F(StringAppleTest, MakeStringFromCFStringRef) {
5152
for (const std::string& string_value : StringTestCases()) {
5253
CFStringRef cf_string = MakeCFString(string_value);
54+
Defer cleanup([&] { SafeCFRelease(cf_string); });
55+
5356
std::string actual = MakeString(cf_string);
5457
EXPECT_EQ(string_value, actual);
55-
CFRelease(cf_string);
5658
}
5759
}
5860

0 commit comments

Comments
 (0)