@react-native-firebase/perf 26.3.3 → 27.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/RNFBPerf.podspec +6 -1
  3. package/android/build.gradle +5 -0
  4. package/android/src/main/java/io/invertase/firebase/perf/RNFBPerfHandleRegistry.kt +71 -0
  5. package/android/src/main/java/io/invertase/firebase/perf/UniversalFirebasePerfModule.java +65 -28
  6. package/android/src/test/java/io/invertase/firebase/perf/RNFBPerfHandleRegistryTest.java +205 -0
  7. package/dist/module/version.js +1 -1
  8. package/dist/typescript/lib/index.d.ts +1 -1
  9. package/dist/typescript/lib/version.d.ts +1 -1
  10. package/ios/RNFBPerf/RNFBPerfHandleRegistry.h +41 -0
  11. package/ios/RNFBPerf/RNFBPerfHandleRegistry.m +87 -0
  12. package/ios/RNFBPerf/RNFBPerfHandleRegistryStorage.swift +58 -0
  13. package/ios/RNFBPerf/RNFBPerfHelper.h +71 -0
  14. package/ios/RNFBPerf/RNFBPerfHelper.m +219 -0
  15. package/ios/RNFBPerf/RNFBPerfHttpMethodMapper.swift +86 -0
  16. package/ios/RNFBPerf/RNFBPerfHttpMetricStopApplier.swift +87 -0
  17. package/ios/RNFBPerf/RNFBPerfModule.mm +41 -174
  18. package/ios/RNFBPerf/RNFBPerfTraceStopApplier.swift +68 -0
  19. package/ios/RNFBPerf.xcodeproj/project.pbxproj +32 -0
  20. package/ios/RNFBPerfUnitTests/HostStubs/Firebase/FIRPerformanceHostStub.m +170 -0
  21. package/ios/RNFBPerfUnitTests/HostStubs/Firebase/Firebase.h +75 -0
  22. package/ios/RNFBPerfUnitTests/HostStubs/RNFBApp/RNFBSharedUtils.h +12 -0
  23. package/ios/RNFBPerfUnitTests/HostStubs/RNFBApp/RNFBSharedUtilsHostStub.m +18 -0
  24. package/ios/RNFBPerfUnitTests/HostStubs/React/RCTBridgeModule.h +10 -0
  25. package/ios/RNFBPerfUnitTests/RNFBPerfHandleRegistryTests.m +169 -0
  26. package/ios/RNFBPerfUnitTests/RNFBPerfHelperHostStubTests.m +200 -0
  27. package/ios/RNFBPerfUnitTests/RNFBPerfHttpMethodMapperFacadeTests.m +52 -0
  28. package/ios/RNFBPerfUnitTests/RNFBPerfHttpMethodMapperTests.swift +92 -0
  29. package/ios/RNFBPerfUnitTests/RNFBPerfHttpMetricStopApplierFacadeTests.m +105 -0
  30. package/ios/RNFBPerfUnitTests/RNFBPerfHttpMetricStopApplierTests.swift +201 -0
  31. package/ios/RNFBPerfUnitTests/RNFBPerfTraceStopApplierFacadeTests.m +75 -0
  32. package/ios/RNFBPerfUnitTests/RNFBPerfTraceStopApplierTests.swift +142 -0
  33. package/ios/RNFBPerfUnitTests/RNFBPerfUnitTests.xcodeproj/project.pbxproj +321 -0
  34. package/ios/RNFBPerfUnitTests/RNFBPerfUnitTests.xcodeproj/xcshareddata/xcschemes/RNFBPerfUnitTests.xcscheme +69 -0
  35. package/lib/version.ts +1 -1
  36. package/package.json +5 -4
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library 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 Foundation
18
+ import XCTest
19
+
20
+ private enum HttpMetricApplyCall: Equatable {
21
+ case attribute(name: String, value: String)
22
+ case responseCode(Int)
23
+ case requestPayloadSize(Int)
24
+ case responsePayloadSize(Int)
25
+ case responseContentType(String)
26
+ }
27
+
28
+ private final class StubHttpMetric: NSObject, RNFBPerfHttpMetricApplying {
29
+ private(set) var calls: [HttpMetricApplyCall] = []
30
+
31
+ func setValue(_ value: String, forAttribute attributeName: String) {
32
+ calls.append(.attribute(name: attributeName, value: value))
33
+ }
34
+
35
+ func setResponseCode(_ responseCode: Int) {
36
+ calls.append(.responseCode(responseCode))
37
+ }
38
+
39
+ func setRequestPayloadSize(_ bytes: Int) {
40
+ calls.append(.requestPayloadSize(bytes))
41
+ }
42
+
43
+ func setResponsePayloadSize(_ bytes: Int) {
44
+ calls.append(.responsePayloadSize(bytes))
45
+ }
46
+
47
+ func setResponseContentType(_ contentType: String) {
48
+ calls.append(.responseContentType(contentType))
49
+ }
50
+ }
51
+
52
+ final class RNFBPerfHttpMetricStopApplierTests: XCTestCase {
53
+ func testAppliesAttributesThenOptionalFieldsInOrder() {
54
+ let metric = StubHttpMetric()
55
+ let attributes: NSDictionary = [
56
+ "attr_a": "alpha",
57
+ "attr_b": "beta",
58
+ ]
59
+
60
+ RNFBPerfHttpMetricStopApplier.apply(
61
+ attributes: attributes,
62
+ httpResponseCode: NSNumber(value: 200),
63
+ requestPayloadSize: NSNumber(value: 128),
64
+ responsePayloadSize: NSNumber(value: 256),
65
+ responseContentType: "application/json",
66
+ to: metric
67
+ )
68
+
69
+ let attributeCalls = metric.calls.compactMap { call -> (String, String)? in
70
+ if case let .attribute(name, value) = call { return (name, value) }
71
+ return nil
72
+ }
73
+ XCTAssertEqual(attributeCalls.count, 2)
74
+ XCTAssertEqual(Dictionary(uniqueKeysWithValues: attributeCalls)["attr_a"], "alpha")
75
+ XCTAssertEqual(Dictionary(uniqueKeysWithValues: attributeCalls)["attr_b"], "beta")
76
+
77
+ let nonAttributeCalls = metric.calls.filter {
78
+ if case .attribute = $0 { return false }
79
+ return true
80
+ }
81
+ XCTAssertEqual(
82
+ nonAttributeCalls,
83
+ [
84
+ .responseCode(200),
85
+ .requestPayloadSize(128),
86
+ .responsePayloadSize(256),
87
+ .responseContentType("application/json"),
88
+ ]
89
+ )
90
+
91
+ let lastAttributeIndex = metric.calls.lastIndex {
92
+ if case .attribute = $0 { return true }
93
+ return false
94
+ }
95
+ let firstOptionalIndex = metric.calls.firstIndex {
96
+ if case .attribute = $0 { return false }
97
+ return true
98
+ }
99
+ XCTAssertNotNil(lastAttributeIndex)
100
+ XCTAssertNotNil(firstOptionalIndex)
101
+ XCTAssertLessThan(lastAttributeIndex!, firstOptionalIndex!)
102
+ }
103
+
104
+ func testNilAttributesAndNilOptionalsAreNoOps() {
105
+ let metric = StubHttpMetric()
106
+ RNFBPerfHttpMetricStopApplier.apply(
107
+ attributes: nil,
108
+ httpResponseCode: nil,
109
+ requestPayloadSize: nil,
110
+ responsePayloadSize: nil,
111
+ responseContentType: nil,
112
+ to: metric
113
+ )
114
+ XCTAssertTrue(metric.calls.isEmpty)
115
+ }
116
+
117
+ func testEmptyAttributesDictionaryIsNoOp() {
118
+ let metric = StubHttpMetric()
119
+ RNFBPerfHttpMetricStopApplier.apply(
120
+ attributes: [:],
121
+ httpResponseCode: nil,
122
+ requestPayloadSize: nil,
123
+ responsePayloadSize: nil,
124
+ responseContentType: nil,
125
+ to: metric
126
+ )
127
+ XCTAssertTrue(metric.calls.isEmpty)
128
+ }
129
+
130
+ func testAttributesOnly() {
131
+ let metric = StubHttpMetric()
132
+ RNFBPerfHttpMetricStopApplier.apply(
133
+ attributes: ["region": "us"],
134
+ httpResponseCode: nil,
135
+ requestPayloadSize: nil,
136
+ responsePayloadSize: nil,
137
+ responseContentType: nil,
138
+ to: metric
139
+ )
140
+ XCTAssertEqual(metric.calls, [.attribute(name: "region", value: "us")])
141
+ }
142
+
143
+ func testOptionalsOnlySkipsMissingFields() {
144
+ let metric = StubHttpMetric()
145
+ RNFBPerfHttpMetricStopApplier.apply(
146
+ attributes: nil,
147
+ httpResponseCode: NSNumber(value: 404),
148
+ requestPayloadSize: nil,
149
+ responsePayloadSize: NSNumber(value: 10),
150
+ responseContentType: nil,
151
+ to: metric
152
+ )
153
+ XCTAssertEqual(
154
+ metric.calls,
155
+ [
156
+ .responseCode(404),
157
+ .responsePayloadSize(10),
158
+ ]
159
+ )
160
+ }
161
+
162
+ func testSkipsNonStringAttributeValues() {
163
+ let metric = StubHttpMetric()
164
+ let attributes: NSDictionary = [
165
+ "ok": "yes",
166
+ "bad": NSNumber(value: 9),
167
+ ]
168
+
169
+ RNFBPerfHttpMetricStopApplier.apply(
170
+ attributes: attributes,
171
+ httpResponseCode: nil,
172
+ requestPayloadSize: nil,
173
+ responsePayloadSize: nil,
174
+ responseContentType: nil,
175
+ to: metric
176
+ )
177
+
178
+ XCTAssertEqual(metric.calls, [.attribute(name: "ok", value: "yes")])
179
+ }
180
+
181
+ func testNSNumberIntValuesPassedThrough() {
182
+ let metric = StubHttpMetric()
183
+ RNFBPerfHttpMetricStopApplier.apply(
184
+ attributes: nil,
185
+ httpResponseCode: NSNumber(value: Int32.max),
186
+ requestPayloadSize: NSNumber(value: 0),
187
+ responsePayloadSize: NSNumber(value: -1),
188
+ responseContentType: "text/plain",
189
+ to: metric
190
+ )
191
+ XCTAssertEqual(
192
+ metric.calls,
193
+ [
194
+ .responseCode(Int(Int32.max)),
195
+ .requestPayloadSize(0),
196
+ .responsePayloadSize(-1),
197
+ .responseContentType("text/plain"),
198
+ ]
199
+ )
200
+ }
201
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library 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 <XCTest/XCTest.h>
18
+
19
+ #import "RNFBHandleMapStorage-Swift.inc"
20
+
21
+ @interface RNFBPerfTraceStopApplierFacadeStub : NSObject <RNFBPerfTraceApplying>
22
+ @property(nonatomic, strong) NSMutableArray<NSDictionary *> *calls;
23
+ @end
24
+
25
+ @implementation RNFBPerfTraceStopApplierFacadeStub
26
+ - (instancetype)init {
27
+ self = [super init];
28
+ if (self) {
29
+ _calls = [NSMutableArray array];
30
+ }
31
+ return self;
32
+ }
33
+
34
+ - (void)setIntValue:(int64_t)value forMetric:(NSString *)metricName {
35
+ [self.calls addObject:@{@"kind" : @"metric", @"name" : metricName, @"value" : @(value)}];
36
+ }
37
+
38
+ - (void)setValue:(NSString *)value forAttribute:(NSString *)attributeName {
39
+ [self.calls addObject:@{@"kind" : @"attribute", @"name" : attributeName, @"value" : value}];
40
+ }
41
+ @end
42
+
43
+ @interface RNFBPerfTraceStopApplierFacadeTests : XCTestCase
44
+ @end
45
+
46
+ @implementation RNFBPerfTraceStopApplierFacadeTests
47
+
48
+ - (void)testObjCSelectorAppliesMetricsThenAttributes {
49
+ RNFBPerfTraceStopApplierFacadeStub *stub = [[RNFBPerfTraceStopApplierFacadeStub alloc] init];
50
+ NSDictionary *metrics = @{@"m1" : @11};
51
+ NSDictionary *attributes = @{@"a1" : @"v1"};
52
+
53
+ [RNFBPerfTraceStopApplier applyMetrics:metrics attributes:attributes to:stub];
54
+
55
+ XCTAssertEqual(stub.calls.count, 2u);
56
+ XCTAssertEqualObjects(stub.calls[0][@"kind"], @"metric");
57
+ XCTAssertEqualObjects(stub.calls[0][@"name"], @"m1");
58
+ XCTAssertEqualObjects(stub.calls[0][@"value"], @11);
59
+ XCTAssertEqualObjects(stub.calls[1][@"kind"], @"attribute");
60
+ XCTAssertEqualObjects(stub.calls[1][@"name"], @"a1");
61
+ XCTAssertEqualObjects(stub.calls[1][@"value"], @"v1");
62
+ }
63
+
64
+ - (void)testObjCSelectorNilDictionariesAreNoOps {
65
+ RNFBPerfTraceStopApplierFacadeStub *stub = [[RNFBPerfTraceStopApplierFacadeStub alloc] init];
66
+ [RNFBPerfTraceStopApplier applyMetrics:nil attributes:nil to:stub];
67
+ XCTAssertEqual(stub.calls.count, 0u);
68
+ }
69
+
70
+ - (void)testFacadePublicSelectorUnchanged {
71
+ XCTAssertTrue([RNFBPerfTraceStopApplier respondsToSelector:@selector(applyMetrics:
72
+ attributes:to:)]);
73
+ }
74
+
75
+ @end
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library 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 Foundation
18
+ import XCTest
19
+
20
+ private enum TraceApplyCall: Equatable {
21
+ case metric(name: String, value: Int64)
22
+ case attribute(name: String, value: String)
23
+ }
24
+
25
+ private final class StubTrace: NSObject, RNFBPerfTraceApplying {
26
+ private(set) var calls: [TraceApplyCall] = []
27
+
28
+ func setIntValue(_ value: Int64, forMetric metricName: String) {
29
+ calls.append(.metric(name: metricName, value: value))
30
+ }
31
+
32
+ func setValue(_ value: String, forAttribute attributeName: String) {
33
+ calls.append(.attribute(name: attributeName, value: value))
34
+ }
35
+ }
36
+
37
+ final class RNFBPerfTraceStopApplierTests: XCTestCase {
38
+ func testAppliesMetricsThenAttributes() {
39
+ let trace = StubTrace()
40
+ let metrics: NSDictionary = [
41
+ "metric_a": NSNumber(value: 42),
42
+ "metric_b": NSNumber(value: Int64(-7)),
43
+ ]
44
+ let attributes: NSDictionary = [
45
+ "attr_a": "alpha",
46
+ "attr_b": "beta",
47
+ ]
48
+
49
+ RNFBPerfTraceStopApplier.apply(metrics: metrics, attributes: attributes, to: trace)
50
+
51
+ let metricCalls = trace.calls.compactMap { call -> (String, Int64)? in
52
+ if case let .metric(name, value) = call { return (name, value) }
53
+ return nil
54
+ }
55
+ let attributeCalls = trace.calls.compactMap { call -> (String, String)? in
56
+ if case let .attribute(name, value) = call { return (name, value) }
57
+ return nil
58
+ }
59
+
60
+ XCTAssertEqual(metricCalls.count, 2)
61
+ XCTAssertEqual(attributeCalls.count, 2)
62
+ XCTAssertEqual(Dictionary(uniqueKeysWithValues: metricCalls)["metric_a"], 42)
63
+ XCTAssertEqual(Dictionary(uniqueKeysWithValues: metricCalls)["metric_b"], -7)
64
+ XCTAssertEqual(Dictionary(uniqueKeysWithValues: attributeCalls)["attr_a"], "alpha")
65
+ XCTAssertEqual(Dictionary(uniqueKeysWithValues: attributeCalls)["attr_b"], "beta")
66
+
67
+ // Metrics finish before any attribute (pre-port order).
68
+ let firstAttributeIndex = trace.calls.firstIndex { call in
69
+ if case .attribute = call { return true }
70
+ return false
71
+ }
72
+ let lastMetricIndex = trace.calls.lastIndex { call in
73
+ if case .metric = call { return true }
74
+ return false
75
+ }
76
+ XCTAssertNotNil(firstAttributeIndex)
77
+ XCTAssertNotNil(lastMetricIndex)
78
+ XCTAssertLessThan(lastMetricIndex!, firstAttributeIndex!)
79
+ }
80
+
81
+ func testNilDictionariesAreNoOps() {
82
+ let trace = StubTrace()
83
+ RNFBPerfTraceStopApplier.apply(metrics: nil, attributes: nil, to: trace)
84
+ XCTAssertTrue(trace.calls.isEmpty)
85
+ }
86
+
87
+ func testEmptyDictionariesAreNoOps() {
88
+ let trace = StubTrace()
89
+ RNFBPerfTraceStopApplier.apply(metrics: [:], attributes: [:], to: trace)
90
+ XCTAssertTrue(trace.calls.isEmpty)
91
+ }
92
+
93
+ func testMetricsOnly() {
94
+ let trace = StubTrace()
95
+ RNFBPerfTraceStopApplier.apply(
96
+ metrics: ["bytes": NSNumber(value: Int64(1_024))],
97
+ attributes: nil,
98
+ to: trace
99
+ )
100
+ XCTAssertEqual(trace.calls, [.metric(name: "bytes", value: 1024)])
101
+ }
102
+
103
+ func testAttributesOnly() {
104
+ let trace = StubTrace()
105
+ RNFBPerfTraceStopApplier.apply(
106
+ metrics: nil,
107
+ attributes: ["region": "us"],
108
+ to: trace
109
+ )
110
+ XCTAssertEqual(trace.calls, [.attribute(name: "region", value: "us")])
111
+ }
112
+
113
+ func testSkipsNonNumberMetricValuesAndNonStringAttributeValues() {
114
+ let trace = StubTrace()
115
+ let metrics: NSDictionary = [
116
+ "ok": NSNumber(value: 1),
117
+ "bad": "not-a-number",
118
+ ]
119
+ let attributes: NSDictionary = [
120
+ "ok": "yes",
121
+ "bad": NSNumber(value: 9),
122
+ ]
123
+
124
+ RNFBPerfTraceStopApplier.apply(metrics: metrics, attributes: attributes, to: trace)
125
+
126
+ XCTAssertEqual(trace.calls, [
127
+ .metric(name: "ok", value: 1),
128
+ .attribute(name: "ok", value: "yes"),
129
+ ])
130
+ }
131
+
132
+ func testLongLongMetricValues() {
133
+ let trace = StubTrace()
134
+ let big = Int64.max
135
+ RNFBPerfTraceStopApplier.apply(
136
+ metrics: ["max": NSNumber(value: big)],
137
+ attributes: nil,
138
+ to: trace
139
+ )
140
+ XCTAssertEqual(trace.calls, [.metric(name: "max", value: big)])
141
+ }
142
+ }