Files
divkit/client/ios/DivKitTests/Extensions/DivDataPatchExtensionsTests.swift
burstein f7031f1ca1 Reset local triggers when div patch is applied
70f89ed3f3ab4581744642325b3214b3a3b524ab
2024-08-05 17:06:53 +03:00

472 lines
11 KiB
Swift

@testable import DivKit
import XCTest
import VGSL
final class DivDataPatchExtensionsTests: XCTestCase {
private var callbacksCount = 0
private lazy var divPatchCallbacks = Callbacks { _ in
self.callbacksCount += 1
}
func test_WhenNoSuitableChanges_DoesNothing() throws {
let originalData = divData(
divContainer(
items: [
divText(id: "some_div", text: "Old text"),
divSeparator(),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_replace", divSeparator())
)
XCTAssertEqual(patchedData, originalData)
}
func test_WhenReplacingRootDiv_ReplacesDiv() throws {
let originalData = divData(
divText(id: "div_to_replace", text: "Old text")
)
let patchedData = originalData.applyPatch(
("div_to_replace", newDivText1)
)
let expectedData = divData(
newDivText1
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenReplacingDivWithDifferentType_ReplacesDiv() throws {
let oridinalData = divData(
divText(id: "div_to_replace", text: "Old text")
)
let patchedData = oridinalData.applyPatch(
("div_to_replace", divSeparator())
)
let expectedData = divData(
divSeparator()
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenDeletingRootDiv_DoesNothing() throws {
let originalData = divData(
divText(id: "div_to_delete", text: "Old text")
)
let patchedData = originalData.applyPatch(
("div_to_delete", nil)
)
XCTAssertEqual(patchedData, originalData)
}
func test_WhenReplacingRootDivWithMultipleDivs_DoesNothing() throws {
let originalData = divData(
divText(id: "div_to_replace", text: "Old text")
)
let patchedData = originalData.applyPatch(
("div_to_replace", [newDivText1, newDivText2])
)
XCTAssertEqual(patchedData, originalData)
}
func test_WhenReplacingItemInContainer_ReplacesDiv() throws {
let originalData = divData(
divContainer(
items: [
divSeparator(),
divText(id: "div_to_replace", text: "Old text"),
divSeparator(),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_replace", newDivText1)
)
let expectedData = divData(
divContainer(
items: [
divSeparator(),
newDivText1,
divSeparator(),
]
)
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenReplacingItemsInContainer_ReplacesDivs() throws {
let originalData = divData(
divContainer(
items: [
divSeparator(),
divText(id: "div_to_replace", text: "Old text"),
divSeparator(),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_replace", [newDivText1, newDivText2])
)
let expectedData = divData(
divContainer(
items: [
divSeparator(),
newDivText1,
newDivText2,
divSeparator(),
]
)
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenDeletingItemInContainer_RemovesDiv() throws {
let originalData = divData(
divContainer(
items: [
divSeparator(),
divText(id: "div_to_delete", text: "Old text"),
divSeparator(),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_delete", nil)
)
let expectedData = divData(
divContainer(
items: [
divSeparator(),
divSeparator(),
]
)
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenHaveMultipleChanges_AppliesAll() throws {
let originalData = divData(
divContainer(
items: [
divSeparator(),
divText(id: "div_to_replace", text: "Old text"),
divText(id: "div_to_delete", text: "Text to delete"),
divSeparator(),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_replace", [newDivText1, newDivText2]),
("div_to_delete", nil)
)
let expectedData = divData(
divContainer(
items: [
divSeparator(),
newDivText1,
newDivText2,
divSeparator(),
]
)
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenReplacingItemsInGallery_ReplacesDivs() throws {
let originalData = divData(
divGallery(
items: [
divSeparator(),
divText(id: "div_to_replace", text: "Old text"),
divSeparator(),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_replace", [newDivText1, newDivText2])
)
let expectedData = divData(
divGallery(
items: [
divSeparator(),
newDivText1,
newDivText2,
divSeparator(),
]
)
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenDeletingItemInGallery_RemovesDiv() throws {
let originalData = divData(
divGallery(
items: [
divSeparator(),
divText(id: "div_to_delete", text: "Old text"),
divSeparator(),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_delete", nil)
)
let expectedData = divData(
divGallery(
items: [
divSeparator(),
divSeparator(),
]
)
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenReplacingAndDeletingItemsInGrid_AppliesAll() throws {
let originalData = divData(
divGrid(
columnCount: 1,
items: [
divSeparator(),
divText(id: "div_to_replace", text: "Old text"),
divSeparator(id: "div_to_delete"),
divSeparator(),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_replace", [newDivText1, newDivText2]),
("div_to_delete", nil)
)
let expectedData = divData(
divGrid(
columnCount: 1,
items: [
divSeparator(),
newDivText1,
newDivText2,
divSeparator(),
]
)
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenReplacingAndDeletingItemsInPager_AppliesAll() throws {
let originalData = divData(
makePager(
items: [
divSeparator(),
divText(id: "div_to_replace", text: "Old text"),
divSeparator(id: "div_to_delete"),
divSeparator(),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_replace", [newDivText1, newDivText2]),
("div_to_delete", nil)
)
let expectedData = divData(
makePager(
items: [
divSeparator(),
newDivText1,
newDivText2,
divSeparator(),
]
)
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenReplacingStateDiv_ReplacesDiv() throws {
let originalData = divData(
makeState(
states: [
divText(id: "div_to_replace", text: "Old text"),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_replace", newDivText1)
)
let expectedData = divData(
makeState(
states: [
newDivText1,
]
)
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenDeletingStateDiv_KeepsEmptyState() throws {
let originalData = divData(
makeState(
states: [
divText(id: "div_to_delete", text: "Old text"),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_delete", nil)
)
let expectedData = divData(
makeState(
states: [nil]
)
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenReplacingStateDivWithMultipleDivs_DoesNothing() throws {
let originalData = divData(
makeState(
states: [
divText(id: "div_to_replace", text: "Old text"),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_replace", [newDivText1, newDivText2])
)
XCTAssertEqual(patchedData, originalData)
}
func test_WhenReplacingTabsDiv_ReplacesDiv() throws {
let originalData = divData(
makeTabs(
items: [
divText(id: "div_to_replace", text: "Old text"),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_replace", newDivText1)
)
let expectedData = divData(
makeTabs(
items: [
newDivText1,
]
)
)
XCTAssertEqual(patchedData, expectedData)
}
func test_WhenDeletingTabsDiv_DoesNothing() throws {
let originalData = divData(
makeTabs(
items: [
divText(id: "div_to_delete", text: "Old text"),
]
)
)
let patchedData = originalData.applyPatch(
("div_to_delete", nil)
)
XCTAssertEqual(patchedData, originalData)
}
func test_WhenReplacesSuitableDiv_CallElementChangedCallback() throws {
let originalData = divData(
divContainer(
items: [
divText(id: "some_div", text: "Old text"),
divSeparator(),
]
)
)
_ = originalData.applyPatch(
("some_div", divSeparator()),
callbacks: divPatchCallbacks
)
XCTAssertEqual(callbacksCount, 1)
}
func test_WhenNoSuitableChanges_DoesNotCallElementChangedCallback() throws {
let originalData = divData(
divContainer(
items: [
divText(id: "some_div", text: "Old text"),
divSeparator(),
]
)
)
_ = originalData.applyPatch(
("div_to_replace", divSeparator()),
callbacks: divPatchCallbacks
)
XCTAssertEqual(callbacksCount, 0)
}
func test_WhenReplacingDivInMultipleItemsContainer_CallOnlyElementChangedCallbacks() throws {
let originalData = divData(
divContainer(
items: [
divSeparator(),
divText(id: "div_to_replace", text: "Old text"),
divText(id: "some_div", text: "Old text 2"),
divSeparator(),
]
)
)
_ = originalData.applyPatch(
("div_to_replace", [newDivText1]), ("div_to_replace_2", [newDivText1]),
callbacks: divPatchCallbacks
)
XCTAssertEqual(callbacksCount, 1)
}
}
private let newDivText1 = divText(text: "New text 1")
private let newDivText2 = divText(text: "New text 2")
private func makePager(items: [Div]) -> Div {
divPager(
items: items,
layoutMode: .divPageSize(DivPageSize(pageWidth: DivPercentageSize(value: .value(10))))
)
}
private func makeState(states: [Div?]) -> Div {
divState(
divId: "state",
states: states.enumerated().map { index, div in
divStateState(div: div, stateId: "state_\(index)")
}
)
}
private func makeTabs(items: [Div]) -> Div {
divTabs(
items: items.enumerated().map { index, div in
divTabsItem(div: div, title: "Tab \(index)")
}
)
}
extension DivData {
fileprivate func applyPatch(
_ changes: (String, [Div]?)...,
callbacks: DivPatchCallbacks = Callbacks.empty
) -> DivData {
let patch = DivPatch(
changes: changes.map { id, items in
DivPatch.Change(id: id, items: items)
}
)
return applyPatch(patch, callbacks: callbacks)
}
fileprivate func applyPatch(
_ change: (String, Div),
callbacks: DivPatchCallbacks = Callbacks.empty
) -> DivData {
applyPatch((change.0, [change.1]), callbacks: callbacks)
}
}