Skip to content

Commit

Permalink
Add ability to remove items from a section (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
peteschaffner authored May 12, 2020
1 parent 2cca5c7 commit ddf73c2
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 10 deletions.
20 changes: 20 additions & 0 deletions Sources/Publish/API/PublishingStep.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,26 @@ public extension PublishingStep {
try MarkdownFileHandler().addMarkdownFiles(in: folder, to: &context)
}
}

/// Remove all items matching a predicate, optionally within a specific section.
/// - parameter section: Any specific section to remove all items within.
/// - parameter predicate: Any predicate to filter the items using.
static func removeAllItems(
in section: Site.SectionID? = nil,
matching predicate: Predicate<Item<Site>> = .any
) -> Self {
let nameSuffix = section.map { " in '\($0)'" } ?? ""

return step(named: "Remove items" + nameSuffix) { context in
if let section = section {
context.sections[section].removeItems(matching: predicate)
} else {
for section in context.sections.ids {
context.sections[section].removeItems(matching: predicate)
}
}
}
}

/// Mutate all items matching a predicate, optionally within a specific section.
/// - parameter section: Any specific section to mutate all items within.
Expand Down
31 changes: 21 additions & 10 deletions Sources/Publish/API/Section.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,21 +94,19 @@ public extension Section {
return item
}
}

/// Remove all items within this section matching a given predicate.
/// - Parameter predicate: Any predicate to filter the items based on.
mutating func removeItems(matching predicate: Predicate<Item<Site>> = .any) {
items.removeAll(where: predicate.matches)
rebuildIndexes()
}

/// Sort all items within this section using a closure.
/// - Parameter sorter: The closure to use to sort the items.
mutating func sortItems(by sorter: (Item<Site>, Item<Site>) throws -> Bool) rethrows {
try items.sort(by: sorter)
itemIndexesByPath = [:]
itemIndexesByTag = [:]

for (index, item) in items.enumerated() {
itemIndexesByPath[item.relativePath] = index

for tag in item.tags {
itemIndexesByTag[tag, default: []].insert(index)
}
}
rebuildIndexes()
}
}

Expand Down Expand Up @@ -169,4 +167,17 @@ private extension Section {

lastItemModificationDate = newDate
}

mutating func rebuildIndexes() {
itemIndexesByPath = [:]
itemIndexesByTag = [:]

for (index, item) in items.enumerated() {
itemIndexesByPath[item.relativePath] = index

for tag in item.tags {
itemIndexesByTag[tag, default: []].insert(index)
}
}
}
}
16 changes: 16 additions & 0 deletions Tests/PublishTests/Tests/ContentMutationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ final class ContentMutationTests: PublishTestCase {
XCTAssertEqual(site.sections[.one].items.first?.body.html, "<div>Plot!</div>")
}

func testRemovingItemsMatchingPredicate() throws {
let items = [
Item.stub(withPath: "a").setting(\.tags, to: ["one"]),
Item.stub(withPath: "b").setting(\.tags, to: ["one", "two"])
]

let site = try publishWebsite(using: [
.addItems(in: items),
.removeAllItems(matching: \.tags ~= "two")
])

XCTAssertEqual(site.sections[.one].items, [items[0]])
XCTAssertNil(site.sections[.one].item(at: "b"), "Item indexes not updated")
}

func testMutatingAllSections() throws {
let site = try publishWebsite(using: [
.step(named: "Set section titles") { context in
Expand Down Expand Up @@ -280,6 +295,7 @@ extension ContentMutationTests {
[
("testAddingItemUsingClosureAPI", testAddingItemUsingClosureAPI),
("testAddingItemUsingPlotHierarchy", testAddingItemUsingPlotHierarchy),
("testRemovingItemsMatchingPredicate", testRemovingItemsMatchingPredicate),
("testMutatingAllSections", testMutatingAllSections),
("testMutatingAllItems", testMutatingAllItems),
("testMutatingItemsInSection", testMutatingItemsInSection),
Expand Down

0 comments on commit ddf73c2

Please sign in to comment.