@onekeyfe/react-native-native-list 3.0.157-alpha.253 → 3.0.157-alpha.254

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.
@@ -0,0 +1,90 @@
1
+ import UIKit
2
+ import XCTest
3
+ @testable import NativeListModule
4
+
5
+ @MainActor
6
+ final class NativeListLifecycleTests: XCTestCase {
7
+ func testRebindingAndReuseInvalidateThePreviousActionEpoch() throws {
8
+ let cell = NativeListActionCell(frame: CGRect(x: 0, y: 0, width: 320, height: 60))
9
+ let first = try NativeListItem(data: ["key": "row", "type": "action", "title": "First"])
10
+ let changed = try NativeListItem(data: ["key": "row", "type": "action", "title": "Changed"])
11
+ var invalidatedEpochs: [Int] = []
12
+ cell.onBindingInvalidated = { _, epoch in invalidatedEpochs.append(epoch) }
13
+
14
+ func bind(_ item: NativeListItem) {
15
+ cell.bind(item: item, theme: nil, layout: "linear", selected: false,
16
+ checkboxState: { _, _, fallback in fallback })
17
+ }
18
+
19
+ bind(first)
20
+ let originalEpoch = cell.rowActionOrigin().bindingEpoch
21
+ bind(first)
22
+ XCTAssertEqual(cell.bindingEpoch, originalEpoch, "Identical content should retain its action origin")
23
+ XCTAssertTrue(invalidatedEpochs.isEmpty)
24
+
25
+ bind(changed)
26
+ XCTAssertEqual(invalidatedEpochs, [originalEpoch])
27
+ XCTAssertNotEqual(cell.rowActionOrigin().bindingEpoch, originalEpoch)
28
+
29
+ let changedEpoch = cell.bindingEpoch
30
+ cell.prepareForReuse()
31
+ XCTAssertEqual(invalidatedEpochs, [originalEpoch, changedEpoch])
32
+ XCTAssertNotEqual(cell.bindingEpoch, changedEpoch)
33
+ }
34
+
35
+ func testFixedFooterReplacesRendererAndKeepsActionRouting() throws {
36
+ let view = NativeListView(frame: CGRect(x: 0, y: 0, width: 320, height: 480))
37
+ var actions: [[String: Any]] = []
38
+ view.onRowAction = { payload in
39
+ let data = Data(payload.utf8)
40
+ if let action = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any] {
41
+ actions.append(action)
42
+ }
43
+ }
44
+
45
+ view.applySnapshotJson(try snapshot(footer: [
46
+ "key": "footer", "type": "action", "title": "Continue", "actionKey": "continue",
47
+ ]))
48
+ let first = try XCTUnwrap(footerCell(in: view))
49
+ XCTAssertTrue(first is NativeListActionCell)
50
+ XCTAssertFalse(first.isHidden)
51
+ XCTAssertEqual(first.accessibilityLabel, "Continue")
52
+ let gestureCount = first.gestureRecognizers?.count
53
+
54
+ view.applySnapshotJson(try snapshot(footer: [
55
+ "key": "footer", "type": "system", "variant": "retry", "title": "Retry",
56
+ "actionKey": "retry",
57
+ ]))
58
+ let second = try XCTUnwrap(footerCell(in: view))
59
+ XCTAssertTrue(second is NativeListSystemCell)
60
+ XCTAssertFalse(second === first)
61
+ XCTAssertNil(first.superview)
62
+ XCTAssertFalse(second.isHidden)
63
+ XCTAssertEqual(second.accessibilityLabel, "Retry")
64
+ XCTAssertEqual(second.gestureRecognizers?.count, gestureCount)
65
+
66
+ second.onAction?(try NativeListItem(data: [
67
+ "key": "footer", "type": "system", "variant": "retry", "title": "Retry",
68
+ "actionKey": "retry",
69
+ ]), "retry", nil, nil)
70
+ XCTAssertEqual(actions.last?["actionKey"] as? String, "retry")
71
+
72
+ view.applySnapshotJson(try snapshot(footer: nil))
73
+ XCTAssertTrue(second.isHidden)
74
+ }
75
+
76
+ private func snapshot(footer: [String: Any]?) throws -> String {
77
+ var value: [String: Any] = [
78
+ "schemaVersion": 1, "generation": 1, "layout": ["kind": "linear"], "rows": [],
79
+ ]
80
+ if let footer { value["fixedFooter"] = footer }
81
+ let data = try JSONSerialization.data(withJSONObject: value, options: [.sortedKeys])
82
+ return String(decoding: data, as: UTF8.self)
83
+ }
84
+
85
+ private func footerCell(in view: NativeListView) -> NativeListRowHost? {
86
+ view.subviews.lazy.compactMap { container in
87
+ container.subviews.compactMap { $0 as? NativeListRowHost }.first
88
+ }.first
89
+ }
90
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-native-list",
3
- "version": "3.0.157-alpha.253",
3
+ "version": "3.0.157-alpha.254",
4
4
  "description": "Template-driven native RecyclerView and UICollectionView for React Native",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./lib/module/index.js",
@@ -83,8 +83,8 @@
83
83
  "typescript": "^5.9.2"
84
84
  },
85
85
  "peerDependencies": {
86
- "@onekeyfe/react-native-image": "3.0.157-alpha.253",
87
- "@onekeyfe/react-native-native-logger": "3.0.157-alpha.253",
86
+ "@onekeyfe/react-native-image": "3.0.157-alpha.254",
87
+ "@onekeyfe/react-native-native-logger": "3.0.157-alpha.254",
88
88
  "react": "*",
89
89
  "react-native": "*",
90
90
  "react-native-nitro-modules": "0.37.0"
@@ -13,6 +13,7 @@ Pod::Spec.new do |s|
13
13
  s.module_name = "NativeListModule"
14
14
  s.source = { :git => "https://github.com/OneKeyHQ/app-modules.git", :tag => "#{s.version}" }
15
15
  s.source_files = ["ios/**/*.{swift,h,m,mm,cpp}"]
16
+ s.exclude_files = "ios/tests/**/*"
16
17
  s.resource_bundles = {
17
18
  "NativeListResources" => [
18
19
  "common/fonts/*.ttf",
@@ -32,6 +33,11 @@ Pod::Spec.new do |s|
32
33
  s.dependency "React-jsi"
33
34
  s.dependency "React-callinvoker"
34
35
 
36
+ s.test_spec "Tests" do |test_spec|
37
+ test_spec.source_files = "ios/tests/**/*.swift"
38
+ test_spec.pod_target_xcconfig = { "PRODUCT_MODULE_NAME" => "NativeListModuleTests" }
39
+ end
40
+
35
41
  load "nitrogen/generated/ios/NativeListModule+autolinking.rb"
36
42
  add_nitrogen_files(s)
37
43
  install_modules_dependencies(s)