From 68373ab09c33b4c8493755e9ae522c14a2fe6258 Mon Sep 17 00:00:00 2001 From: mtj0928 Date: Wed, 31 Dec 2025 18:04:19 +0900 Subject: [PATCH] Equatable support on node --- Sources/SGFKit/Collection.swift | 4 ++ Sources/SGFKit/Node.swift | 9 ++- Tests/SGFKitTests/NodeTests.swift | 94 +++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 Tests/SGFKitTests/NodeTests.swift diff --git a/Sources/SGFKit/Collection.swift b/Sources/SGFKit/Collection.swift index 925e447..c3ef8da 100644 --- a/Sources/SGFKit/Collection.swift +++ b/Sources/SGFKit/Collection.swift @@ -47,6 +47,10 @@ extension Collection: NodeProtocol { func node(treeStructureDidUpdated number: Int?) { refreshStructure() } + + public static func == (lhs: Collection, rhs: Collection) -> Bool { + lhs.nodes == rhs.nodes + } } private final class NumberPublisher { diff --git a/Sources/SGFKit/Node.swift b/Sources/SGFKit/Node.swift index a823d17..1dab53b 100644 --- a/Sources/SGFKit/Node.swift +++ b/Sources/SGFKit/Node.swift @@ -1,4 +1,4 @@ -protocol NodeProtocol: AnyObject { +protocol NodeProtocol: AnyObject, Equatable { associatedtype Game: SGFKit.Game var number: Int? { get } @@ -9,6 +9,7 @@ protocol NodeProtocol: AnyObject { /// A node object for SGF. public final class Node { + /// A unique number for the node in the collection. /// /// The numbering rule follows [the official documents rule](https://www.red-bean.com/sgf/sgf4.html#1) @@ -105,6 +106,12 @@ extension Node: NodeProtocol { func node(treeStructureDidUpdated index: Int?) { parent?.node(treeStructureDidUpdated: index) } + + public static func == (lhs: Node, rhs: Node) -> Bool { + lhs.number == rhs.number + && lhs.children == rhs.children + && lhs.properties == rhs.properties + } } /// A struct indicating a raw property of a node. diff --git a/Tests/SGFKitTests/NodeTests.swift b/Tests/SGFKitTests/NodeTests.swift new file mode 100644 index 0000000..48988d7 --- /dev/null +++ b/Tests/SGFKitTests/NodeTests.swift @@ -0,0 +1,94 @@ +@testable import SGFKit +import Testing + +@Suite +struct NodeTests { + + // MARK: - Equatable Tests + + @Test + func equalityWithSameProperties() throws { + let property1 = Property(identifier: "B", values: [.single("cc")]) + let node1 = Node(properties: [property1]) + + let property2 = Property(identifier: "B", values: [.single("cc")]) + let node2 = Node(properties: [property2]) + + #expect(node1 == node2) + } + + @Test + func equalityWithDifferentProperties() throws { + let property1 = Property(identifier: "B", values: [.single("cc")]) + let node1 = Node(properties: [property1]) + + let property2 = Property(identifier: "B", values: [.single("dd")]) + let node2 = Node(properties: [property2]) + + #expect(node1 != node2) + } + + @Test + func equalityWithDifferentNumbers() throws { + let property1 = Property(identifier: "B", values: [.single("cc")]) + let node1 = Node(number: 1, properties: [property1]) + + let property2 = Property(identifier: "B", values: [.single("cc")]) + let node2 = Node(number: 2, properties: [property2]) + + #expect(node1 != node2) + } + + @Test + func equalityWithSameChildren() throws { + let childProperty1 = Property(identifier: "W", values: [.single("dd")]) + let child1 = Node(properties: [childProperty1]) + + let property1 = Property(identifier: "B", values: [.single("cc")]) + let node1 = Node(properties: [property1]) + node1.children = [child1] + + let childProperty2 = Property(identifier: "W", values: [.single("dd")]) + let child2 = Node(properties: [childProperty2]) + + let property2 = Property(identifier: "B", values: [.single("cc")]) + let node2 = Node(properties: [property2]) + node2.children = [child2] + + #expect(node1 == node2) + } + + @Test + func equalityWithDifferentChildren() throws { + let childProperty1 = Property(identifier: "W", values: [.single("dd")]) + let child1 = Node(properties: [childProperty1]) + + let property1 = Property(identifier: "B", values: [.single("cc")]) + let node1 = Node(properties: [property1]) + node1.children = [child1] + + let childProperty2 = Property(identifier: "W", values: [.single("ee")]) + let child2 = Node(properties: [childProperty2]) + + let property2 = Property(identifier: "B", values: [.single("cc")]) + let node2 = Node(properties: [property2]) + node2.children = [child2] + + #expect(node1 != node2) + } + + @Test + func equalityWithDifferentChildrenCount() throws { + let childProperty1 = Property(identifier: "W", values: [.single("dd")]) + let child1 = Node(properties: [childProperty1]) + + let property1 = Property(identifier: "B", values: [.single("cc")]) + let node1 = Node(properties: [property1]) + node1.children = [child1] + + let property2 = Property(identifier: "B", values: [.single("cc")]) + let node2 = Node(properties: [property2]) + + #expect(node1 != node2) + } +}