Implemented some test cases for the "filter(by:)" function of the FeedListViewModel view model in the Feed framework.
This commit is contained in:
parent
5de35984dc
commit
a1abe1f4ae
@ -20,14 +20,14 @@ extension FeedListViewController {
|
|||||||
private let topWords: TopWordsUseCase = .init()
|
private let topWords: TopWordsUseCase = .init()
|
||||||
|
|
||||||
// MARK: Properties
|
// MARK: Properties
|
||||||
@Published var filter: FilterOption = .all
|
@Published private(set) var filter: FilterOption = .all
|
||||||
@Published var isFilterEnabled: Bool = false
|
@Published private(set) var isFilterEnabled: Bool = false
|
||||||
@Published var isFiltering: Bool = false
|
@Published private(set) var isFiltering: Bool = false
|
||||||
@Published var isLoading: Bool = false
|
@Published private(set) var isLoading: Bool = false
|
||||||
@Published var state: FeedListState = .initial
|
@Published private(set) var state: FeedListState = .initial
|
||||||
|
|
||||||
var items: [Review] = []
|
private(set) var items: [Review] = []
|
||||||
var words: [TopWord] = []
|
private(set) var words: [TopWord] = []
|
||||||
|
|
||||||
private var reviewsAll: [Review] = []
|
private var reviewsAll: [Review] = []
|
||||||
private var reviewsFiltered: FilteredReviews = [:]
|
private var reviewsFiltered: FilteredReviews = [:]
|
||||||
|
@ -61,8 +61,6 @@ final class FeedListViewModelTests: XCTestCase {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
sut.fetch()
|
|
||||||
|
|
||||||
sut.$isLoading
|
sut.$isLoading
|
||||||
.collect(3)
|
.collect(3)
|
||||||
.sink { value in
|
.sink { value in
|
||||||
@ -71,7 +69,9 @@ final class FeedListViewModelTests: XCTestCase {
|
|||||||
expectation.fulfill()
|
expectation.fulfill()
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
sut.fetch()
|
||||||
|
|
||||||
wait(for: [expectation], timeout: 2)
|
wait(for: [expectation], timeout: 2)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
@ -96,8 +96,6 @@ final class FeedListViewModelTests: XCTestCase {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
sut.fetch()
|
|
||||||
|
|
||||||
sut.$isLoading
|
sut.$isLoading
|
||||||
.collect(3)
|
.collect(3)
|
||||||
.sink { value in
|
.sink { value in
|
||||||
@ -106,6 +104,8 @@ final class FeedListViewModelTests: XCTestCase {
|
|||||||
expectation.fulfill()
|
expectation.fulfill()
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
sut.fetch()
|
||||||
|
|
||||||
wait(for: [expectation], timeout: 2)
|
wait(for: [expectation], timeout: 2)
|
||||||
|
|
||||||
@ -127,17 +127,17 @@ final class FeedListViewModelTests: XCTestCase {
|
|||||||
MockURLProtocol.response = .init(statusCode: 404)
|
MockURLProtocol.response = .init(statusCode: 404)
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
sut.fetch()
|
|
||||||
|
|
||||||
sut.$isLoading
|
sut.$isLoading
|
||||||
.collect(3)
|
.collect(3)
|
||||||
.sink { value in
|
.sink { value in
|
||||||
isLoading.append(contentsOf: value)
|
isLoading.append(contentsOf: value)
|
||||||
|
|
||||||
expectation.fulfill()
|
expectation.fulfill()
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
sut.fetch()
|
||||||
|
|
||||||
wait(for: [expectation], timeout: 2)
|
wait(for: [expectation], timeout: 2)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
@ -155,16 +155,12 @@ final class FeedListViewModelTests: XCTestCase {
|
|||||||
var isLoading: [Bool] = []
|
var isLoading: [Bool] = []
|
||||||
|
|
||||||
// GIVEN
|
// GIVEN
|
||||||
sut.filter = .only1Star
|
|
||||||
|
|
||||||
MockURLProtocol.response = .init(
|
MockURLProtocol.response = .init(
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
object: Feed(entries: .sample)
|
object: Feed(entries: .sample)
|
||||||
)
|
)
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
sut.fetch()
|
|
||||||
|
|
||||||
sut.$isLoading
|
sut.$isLoading
|
||||||
.collect(3)
|
.collect(3)
|
||||||
.sink { value in
|
.sink { value in
|
||||||
@ -173,11 +169,15 @@ final class FeedListViewModelTests: XCTestCase {
|
|||||||
expectation.fulfill()
|
expectation.fulfill()
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
sut.filter(by: .only1Star)
|
||||||
|
sut.fetch()
|
||||||
|
|
||||||
wait(for: [expectation], timeout: 2)
|
wait(for: [expectation], timeout: 2)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
XCTAssertEqual(isLoading, [false, true, false])
|
XCTAssertEqual(isLoading, [false, true, false])
|
||||||
|
XCTAssertEqual(sut.filter, .only1Star)
|
||||||
XCTAssertTrue(sut.isFilterEnabled)
|
XCTAssertTrue(sut.isFilterEnabled)
|
||||||
XCTAssertTrue(sut.isWordsShowing)
|
XCTAssertTrue(sut.isWordsShowing)
|
||||||
XCTAssertFalse(sut.items.isEmpty)
|
XCTAssertFalse(sut.items.isEmpty)
|
||||||
@ -194,16 +194,12 @@ final class FeedListViewModelTests: XCTestCase {
|
|||||||
var isLoading: [Bool] = []
|
var isLoading: [Bool] = []
|
||||||
|
|
||||||
// GIVEN
|
// GIVEN
|
||||||
sut.filter = .only1Star
|
|
||||||
|
|
||||||
MockURLProtocol.response = .init(
|
MockURLProtocol.response = .init(
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
object: Feed(entries: .none)
|
object: Feed(entries: .none)
|
||||||
)
|
)
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
sut.fetch()
|
|
||||||
|
|
||||||
sut.$isLoading
|
sut.$isLoading
|
||||||
.collect(3)
|
.collect(3)
|
||||||
.sink { value in
|
.sink { value in
|
||||||
@ -213,10 +209,14 @@ final class FeedListViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
sut.filter(by: .only1Star)
|
||||||
|
sut.fetch()
|
||||||
|
|
||||||
wait(for: [expectation], timeout: 2)
|
wait(for: [expectation], timeout: 2)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
XCTAssertEqual(isLoading, [false, true, false])
|
XCTAssertEqual(isLoading, [false, true, false])
|
||||||
|
XCTAssertEqual(sut.filter, .only1Star)
|
||||||
XCTAssertFalse(sut.isFilterEnabled)
|
XCTAssertFalse(sut.isFilterEnabled)
|
||||||
XCTAssertFalse(sut.isWordsShowing)
|
XCTAssertFalse(sut.isWordsShowing)
|
||||||
XCTAssertTrue(sut.items.isEmpty)
|
XCTAssertTrue(sut.items.isEmpty)
|
||||||
@ -231,13 +231,9 @@ final class FeedListViewModelTests: XCTestCase {
|
|||||||
var isLoading: [Bool] = []
|
var isLoading: [Bool] = []
|
||||||
|
|
||||||
// GIVEN
|
// GIVEN
|
||||||
sut.filter = .only1Star
|
|
||||||
|
|
||||||
MockURLProtocol.response = .init(statusCode: 404)
|
MockURLProtocol.response = .init(statusCode: 404)
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
sut.fetch()
|
|
||||||
|
|
||||||
sut.$isLoading
|
sut.$isLoading
|
||||||
.collect(3)
|
.collect(3)
|
||||||
.sink { value in
|
.sink { value in
|
||||||
@ -246,11 +242,15 @@ final class FeedListViewModelTests: XCTestCase {
|
|||||||
expectation.fulfill()
|
expectation.fulfill()
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
sut.filter(by: .only1Star)
|
||||||
|
sut.fetch()
|
||||||
|
|
||||||
wait(for: [expectation], timeout: 2)
|
wait(for: [expectation], timeout: 2)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
XCTAssertEqual(isLoading, [false, true, false])
|
XCTAssertEqual(isLoading, [false, true, false])
|
||||||
|
XCTAssertEqual(sut.filter, .only1Star)
|
||||||
XCTAssertFalse(sut.isFilterEnabled)
|
XCTAssertFalse(sut.isFilterEnabled)
|
||||||
XCTAssertFalse(sut.isWordsShowing)
|
XCTAssertFalse(sut.isWordsShowing)
|
||||||
XCTAssertTrue(sut.items.isEmpty)
|
XCTAssertTrue(sut.items.isEmpty)
|
||||||
@ -259,6 +259,145 @@ final class FeedListViewModelTests: XCTestCase {
|
|||||||
XCTAssertTrue(sut.words.isEmpty)
|
XCTAssertTrue(sut.words.isEmpty)
|
||||||
}
|
}
|
||||||
|
|
||||||
func test
|
func testFilter_forNewOption_withSomeItems() {
|
||||||
|
let expectation = XCTestExpectation()
|
||||||
|
|
||||||
|
var filter: [FilterOption] = []
|
||||||
|
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.response = .init(
|
||||||
|
statusCode: 200,
|
||||||
|
object: Feed(entries: .sample)
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
sut.$filter
|
||||||
|
.dropFirst()
|
||||||
|
.sink { value in
|
||||||
|
filter.append(value)
|
||||||
|
|
||||||
|
expectation.fulfill()
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
sut.fetch()
|
||||||
|
sut.filter(by: .only1Star)
|
||||||
|
|
||||||
|
wait(for: [expectation], timeout: 2)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
XCTAssertEqual(filter, [.only1Star])
|
||||||
|
XCTAssertFalse(sut.items.isEmpty)
|
||||||
|
XCTAssertEqual(sut.items.count, 1)
|
||||||
|
XCTAssertEqual(sut.itemsCount, 2)
|
||||||
|
XCTAssertFalse(sut.words.isEmpty)
|
||||||
|
XCTAssertEqual(sut.words.count, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFilter_forNewOption_withNoItems() {
|
||||||
|
let expectation = XCTestExpectation()
|
||||||
|
|
||||||
|
var filter: [FilterOption] = []
|
||||||
|
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.response = .init(
|
||||||
|
statusCode: 200,
|
||||||
|
object: Feed(entries: .none)
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
sut.$filter
|
||||||
|
.dropFirst()
|
||||||
|
.sink { value in
|
||||||
|
filter.append(value)
|
||||||
|
|
||||||
|
expectation.fulfill()
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
sut.fetch()
|
||||||
|
sut.filter(by: .only1Star)
|
||||||
|
|
||||||
|
wait(for: [expectation], timeout: 2)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
XCTAssertEqual(filter, [.only1Star])
|
||||||
|
XCTAssertTrue(sut.items.isEmpty)
|
||||||
|
XCTAssertEqual(sut.items.count, 0)
|
||||||
|
XCTAssertEqual(sut.itemsCount, 0)
|
||||||
|
XCTAssertTrue(sut.words.isEmpty)
|
||||||
|
XCTAssertEqual(sut.words.count, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFilter_forSameOption_withSomeItems() {
|
||||||
|
let expectation = XCTestExpectation()
|
||||||
|
|
||||||
|
var filter: [FilterOption] = []
|
||||||
|
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.response = .init(
|
||||||
|
statusCode: 200,
|
||||||
|
object: Feed(entries: .sample)
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
sut.$filter
|
||||||
|
.dropFirst()
|
||||||
|
.sink { value in
|
||||||
|
filter.append(value)
|
||||||
|
|
||||||
|
expectation.fulfill()
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
sut.fetch()
|
||||||
|
sut.filter(by: .only1Star)
|
||||||
|
sut.filter(by: .only1Star)
|
||||||
|
|
||||||
|
wait(for: [expectation], timeout: 2)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
XCTAssertEqual(filter, [.only1Star])
|
||||||
|
XCTAssertFalse(sut.items.isEmpty)
|
||||||
|
XCTAssertEqual(sut.items.count, 1)
|
||||||
|
XCTAssertEqual(sut.itemsCount, 2)
|
||||||
|
XCTAssertFalse(sut.words.isEmpty)
|
||||||
|
XCTAssertEqual(sut.words.count, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFilter_forSameOption_withNoItems() {
|
||||||
|
let expectation = XCTestExpectation()
|
||||||
|
|
||||||
|
var filter: [FilterOption] = []
|
||||||
|
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.response = .init(
|
||||||
|
statusCode: 200,
|
||||||
|
object: Feed(entries: .none)
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
sut.$filter
|
||||||
|
.dropFirst()
|
||||||
|
.sink { value in
|
||||||
|
filter.append(value)
|
||||||
|
|
||||||
|
expectation.fulfill()
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
sut.fetch()
|
||||||
|
sut.filter(by: .only1Star)
|
||||||
|
|
||||||
|
wait(for: [expectation], timeout: 2)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
XCTAssertEqual(filter, [.only1Star])
|
||||||
|
XCTAssertTrue(sut.items.isEmpty)
|
||||||
|
XCTAssertEqual(sut.items.count, 0)
|
||||||
|
XCTAssertEqual(sut.itemsCount, 0)
|
||||||
|
XCTAssertTrue(sut.words.isEmpty)
|
||||||
|
XCTAssertEqual(sut.words.count, 0)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user