Implemented the TopWordsUseCase use case in the Filter library.
This commit is contained in:
parent
b01ec5ec67
commit
75e1e071cf
@ -69,11 +69,6 @@ public struct FilterWordsUseCase {
|
||||
)
|
||||
}
|
||||
|
||||
print("WORD TERMS: \(terms)")
|
||||
print("WORD ALL: \(wordsAll)")
|
||||
print("WORD COUNT: \(wordsCount)")
|
||||
print("WORD UNIQUE: \(wordsUnique)")
|
||||
|
||||
return wordsUnique.sorted {
|
||||
guard $0.count != $1.count else {
|
||||
return $0.word.token < $1.word.token
|
||||
|
58
Libraries/Filter/Kit/Sources/Use Cases/TopWordsUseCase.swift
Normal file
58
Libraries/Filter/Kit/Sources/Use Cases/TopWordsUseCase.swift
Normal file
@ -0,0 +1,58 @@
|
||||
//
|
||||
// TopWordsUseCase.swift
|
||||
// ReviewsParserKit
|
||||
//
|
||||
// Created by Javier Cicchelli on 18/03/2024.
|
||||
// Copyright © 2024 Röck+Cöde VoF. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct TopWordsUseCase {
|
||||
|
||||
// MARK: Type aliases
|
||||
public typealias Input = [[WordCount]]
|
||||
public typealias Output = [WordCount]
|
||||
|
||||
// MARK: Initialisers
|
||||
public init() {}
|
||||
|
||||
// MARK: Functions
|
||||
public func callAsFunction(_ input: Input) -> Output {
|
||||
let wordCounts = input
|
||||
.reduce([WordCount](), +)
|
||||
.reduce(into: [WordCount]()) { partialResult, wordCount in
|
||||
guard
|
||||
let wordCountFound = partialResult.first(where: { $0.word == wordCount.word })
|
||||
else {
|
||||
partialResult.append(wordCount)
|
||||
return
|
||||
}
|
||||
|
||||
partialResult.removeAll { $0 == wordCountFound }
|
||||
partialResult.append(.init(
|
||||
word: wordCount.word,
|
||||
count: wordCount.count + wordCountFound.count
|
||||
))
|
||||
}
|
||||
.sorted {
|
||||
guard $0.count != $1.count else {
|
||||
return $0.word.token < $1.word.token
|
||||
}
|
||||
|
||||
return $0.count > $1.count
|
||||
}
|
||||
|
||||
return wordCounts.count >= .Max.words
|
||||
? Array(wordCounts[0...2])
|
||||
: wordCounts
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Int+Constants
|
||||
private extension Int {
|
||||
enum Max {
|
||||
static let words: Int = 3
|
||||
}
|
||||
}
|
110
Libraries/Filter/Test/Tests/Use Cases/TopWordsUseCaseTests.swift
Normal file
110
Libraries/Filter/Test/Tests/Use Cases/TopWordsUseCaseTests.swift
Normal file
@ -0,0 +1,110 @@
|
||||
//
|
||||
// TopWordsUseCaseTests.swift
|
||||
// ReviewsFilterTest
|
||||
//
|
||||
// Created by Javier Cicchelli on 18/03/2024.
|
||||
// Copyright © 2024 Röck+Cöde VoF. All rights reserved.
|
||||
//
|
||||
|
||||
import ReviewsFilterKit
|
||||
import XCTest
|
||||
|
||||
final class TopWordsUseCaseTests: XCTestCase {
|
||||
|
||||
// MARK: Properties
|
||||
private var input: TopWordsUseCase.Input!
|
||||
private var output: TopWordsUseCase.Output!
|
||||
private var sut: TopWordsUseCase!
|
||||
|
||||
// MARK: Setup
|
||||
override func setUp() async throws {
|
||||
sut = .init()
|
||||
}
|
||||
|
||||
// MARK: Functions
|
||||
func testCallAsFunction_withInput_hasDifferentWords() {
|
||||
// GIVEN
|
||||
input = [[
|
||||
.init(word: .init(term: "One", token: "one"), count: 3)
|
||||
], [
|
||||
.init(word: .init(term: "Two", token: "two"), count: 1)
|
||||
], [
|
||||
.init(word: .init(term: "Three", token: "three"), count: 5),
|
||||
.init(word: .init(term: "Four", token: "four"), count: 2),
|
||||
]]
|
||||
|
||||
// WHEN
|
||||
output = sut(input)
|
||||
|
||||
// THEN
|
||||
XCTAssertFalse(output.isEmpty)
|
||||
XCTAssertEqual(output.count, 3)
|
||||
XCTAssertEqual(output, [
|
||||
.init(word: .init(term: "Three", token: "three"), count: 5),
|
||||
.init(word: .init(term: "One", token: "one"), count: 3),
|
||||
.init(word: .init(term: "Four", token: "four"), count: 2)
|
||||
])
|
||||
}
|
||||
|
||||
func testCallAsFunction_withInput_hasSomeCommonWords() {
|
||||
// GIVEN
|
||||
input = [[
|
||||
.init(word: .init(term: "One", token: "one"), count: 3),
|
||||
.init(word: .init(term: "Two", token: "two"), count: 7),
|
||||
.init(word: .init(term: "Three", token: "three"), count: 1),
|
||||
], [
|
||||
.init(word: .init(term: "Four", token: "four"), count: 5),
|
||||
.init(word: .init(term: "Two", token: "two"), count: 2),
|
||||
.init(word: .init(term: "Five", token: "five"), count: 6),
|
||||
], [
|
||||
.init(word: .init(term: "Six", token: "six"), count: 9),
|
||||
.init(word: .init(term: "Four", token: "four"), count: 4),
|
||||
.init(word: .init(term: "Two", token: "two"), count: 1),
|
||||
]]
|
||||
|
||||
// WHEN
|
||||
output = sut(input)
|
||||
|
||||
// THEN
|
||||
XCTAssertFalse(output.isEmpty)
|
||||
XCTAssertEqual(output.count, 3)
|
||||
XCTAssertEqual(output, [
|
||||
.init(word: .init(term: "Two", token: "two"), count: 10),
|
||||
.init(word: .init(term: "Four", token: "four"), count: 9),
|
||||
.init(word: .init(term: "Six", token: "six"), count: 9)
|
||||
])
|
||||
}
|
||||
|
||||
func testCallAsFunction_withInput_hasFewWords() {
|
||||
// GIVEN
|
||||
input = [[
|
||||
.init(word: .init(term: "One", token: "one"), count: 3),
|
||||
], [
|
||||
.init(word: .init(term: "Four", token: "four"), count: 5),
|
||||
]]
|
||||
|
||||
// WHEN
|
||||
output = sut(input)
|
||||
|
||||
// THEN
|
||||
XCTAssertFalse(output.isEmpty)
|
||||
XCTAssertEqual(output.count, 2)
|
||||
XCTAssertEqual(output, [
|
||||
.init(word: .init(term: "Four", token: "four"), count: 5),
|
||||
.init(word: .init(term: "One", token: "one"), count: 3)
|
||||
])
|
||||
}
|
||||
|
||||
func testCallAsFunction_withEmptyInput() {
|
||||
// GIVEN
|
||||
input = []
|
||||
|
||||
// WHEN
|
||||
output = sut(input)
|
||||
|
||||
// THEN
|
||||
XCTAssertTrue(output.isEmpty)
|
||||
XCTAssertEqual(output, [])
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user