| Index: ios/chrome/browser/ui/collection_view/collection_view_model_unittest.mm
|
| diff --git a/ios/chrome/browser/ui/collection_view/collection_view_model_unittest.mm b/ios/chrome/browser/ui/collection_view/collection_view_model_unittest.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..922bdd37a33512dc88ce0fdc7f8b7a0ce69d8370
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/ui/collection_view/collection_view_model_unittest.mm
|
| @@ -0,0 +1,591 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
|
| +
|
| +#include "base/mac/foundation_util.h"
|
| +#include "base/mac/scoped_nsobject.h"
|
| +#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "testing/gtest_mac.h"
|
| +
|
| +@interface CollectionViewModel (Testing)
|
| +// Adds an item with the given type to the section with the given identifier.
|
| +// It is possible to add multiple items with the same type to the same section.
|
| +// Sharing types across sections is undefined behavior.
|
| +- (void)addItemWithType:(NSInteger)itemType
|
| + toSectionWithIdentifier:(NSInteger)sectionIdentifier;
|
| +@end
|
| +
|
| +@implementation CollectionViewModel (Testing)
|
| +
|
| +- (void)addItemWithType:(NSInteger)itemType
|
| + toSectionWithIdentifier:(NSInteger)sectionIdentifier {
|
| + base::scoped_nsobject<CollectionViewItem> item(
|
| + [[CollectionViewItem alloc] initWithType:itemType]);
|
| + [self addItem:item toSectionWithIdentifier:sectionIdentifier];
|
| +}
|
| +
|
| +@end
|
| +
|
| +namespace {
|
| +
|
| +typedef NS_ENUM(NSInteger, SectionIdentifier) {
|
| + SectionIdentifierCheese = kSectionIdentifierEnumZero,
|
| + SectionIdentifierWeasley,
|
| +};
|
| +
|
| +typedef NS_ENUM(NSInteger, ItemType) {
|
| + ItemTypeCheeseHeader = kItemTypeEnumZero,
|
| + ItemTypeCheeseCheddar,
|
| + ItemTypeCheeseGouda,
|
| + ItemTypeCheesePepperJack,
|
| + ItemTypeWeasleyRon,
|
| + ItemTypeWeasleyGinny,
|
| + ItemTypeWeasleyArthur,
|
| + ItemTypeWeasleyFooter,
|
| +};
|
| +
|
| +void LogSink(const std::string& str) {
|
| + // No-op.
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, EmptyModel) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + // Check there are no items.
|
| + EXPECT_EQ(NO, [model hasItemAtIndexPath:[NSIndexPath indexPathForItem:0
|
| + inSection:0]]);
|
| +
|
| + // Check the collection view data sourcing methods.
|
| + EXPECT_EQ(0, [model numberOfSections]);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, SingleSection) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheeseCheddar
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheeseGouda
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheesePepperJack
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| +
|
| + // Check there are some items but not more.
|
| + EXPECT_EQ(YES, [model hasItemAtIndexPath:[NSIndexPath indexPathForItem:0
|
| + inSection:0]]);
|
| + EXPECT_EQ(YES, [model hasItemAtIndexPath:[NSIndexPath indexPathForItem:2
|
| + inSection:0]]);
|
| + EXPECT_EQ(NO, [model hasItemAtIndexPath:[NSIndexPath indexPathForItem:3
|
| + inSection:0]]);
|
| + EXPECT_EQ(NO, [model hasItemAtIndexPath:[NSIndexPath indexPathForItem:0
|
| + inSection:1]]);
|
| +
|
| + // Check the collection view data sourcing methods.
|
| + EXPECT_EQ(1, [model numberOfSections]);
|
| + EXPECT_EQ(3, [model numberOfItemsInSection:0]);
|
| +
|
| + // Check the section identifier <-> section correspondance methods.
|
| + EXPECT_EQ(SectionIdentifierCheese, [model sectionIdentifierForSection:0]);
|
| + EXPECT_EQ(0, [model sectionForSectionIdentifier:SectionIdentifierCheese]);
|
| +
|
| + // Check the item type <-> item correspondance methods.
|
| + EXPECT_EQ(ItemTypeCheeseCheddar,
|
| + [model itemTypeForIndexPath:[NSIndexPath indexPathForItem:0
|
| + inSection:0]]);
|
| + EXPECT_EQ(ItemTypeCheeseGouda,
|
| + [model itemTypeForIndexPath:[NSIndexPath indexPathForItem:1
|
| + inSection:0]]);
|
| + EXPECT_EQ(ItemTypeCheesePepperJack,
|
| + [model itemTypeForIndexPath:[NSIndexPath indexPathForItem:2
|
| + inSection:0]]);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, SingleSectionWithMissingItems) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheeseCheddar
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + // "Gouda" is intentionally omitted.
|
| + [model addItemWithType:ItemTypeCheesePepperJack
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| +
|
| + // Check the item type <-> item correspondance methods.
|
| + EXPECT_EQ(ItemTypeCheeseCheddar,
|
| + [model itemTypeForIndexPath:[NSIndexPath indexPathForItem:0
|
| + inSection:0]]);
|
| + EXPECT_EQ(ItemTypeCheesePepperJack,
|
| + [model itemTypeForIndexPath:[NSIndexPath indexPathForItem:1
|
| + inSection:0]]);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, MultipleSections) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + // "Cheddar" and "Gouda" are intentionally omitted.
|
| + [model addItemWithType:ItemTypeCheesePepperJack
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierWeasley];
|
| + // "Ron" is intentionally omitted.
|
| + [model addItemWithType:ItemTypeWeasleyGinny
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| +
|
| + // Check the collection view data sourcing methods.
|
| + EXPECT_EQ(2, [model numberOfSections]);
|
| + EXPECT_EQ(2, [model numberOfItemsInSection:1]);
|
| +
|
| + // Check the section identifier <-> section correspondance methods.
|
| + EXPECT_EQ(SectionIdentifierCheese, [model sectionIdentifierForSection:0]);
|
| + EXPECT_EQ(0, [model sectionForSectionIdentifier:SectionIdentifierCheese]);
|
| + EXPECT_EQ(SectionIdentifierWeasley, [model sectionIdentifierForSection:1]);
|
| + EXPECT_EQ(1, [model sectionForSectionIdentifier:SectionIdentifierWeasley]);
|
| +
|
| + // Check the item type <-> item correspondance methods.
|
| + EXPECT_EQ(ItemTypeCheesePepperJack,
|
| + [model itemTypeForIndexPath:[NSIndexPath indexPathForItem:0
|
| + inSection:0]]);
|
| + EXPECT_EQ(ItemTypeWeasleyGinny,
|
| + [model itemTypeForIndexPath:[NSIndexPath indexPathForItem:0
|
| + inSection:1]]);
|
| + EXPECT_EQ(ItemTypeWeasleyArthur,
|
| + [model itemTypeForIndexPath:[NSIndexPath indexPathForItem:1
|
| + inSection:1]]);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, GetIndexPathFromModelCoordinates) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheesePepperJack
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyGinny
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| +
|
| + // Check the index path retrieval method for a single item.
|
| + NSIndexPath* indexPath =
|
| + [model indexPathForItemType:ItemTypeWeasleyGinny
|
| + sectionIdentifier:SectionIdentifierWeasley];
|
| + EXPECT_EQ(1, indexPath.section);
|
| + EXPECT_EQ(0, indexPath.item);
|
| +
|
| + // Check the index path retrieval method for the first item.
|
| + indexPath = [model indexPathForItemType:ItemTypeWeasleyGinny
|
| + sectionIdentifier:SectionIdentifierWeasley
|
| + atIndex:0];
|
| + EXPECT_EQ(1, indexPath.section);
|
| + EXPECT_EQ(0, indexPath.item);
|
| +}
|
| +
|
| +TEST(CollectionViewItemTest, RepeatedItems) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheesePepperJack
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyGinny
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| +
|
| + NSIndexPath* indexPath =
|
| + [model indexPathForItemType:ItemTypeWeasleyArthur
|
| + sectionIdentifier:SectionIdentifierWeasley];
|
| +
|
| + // Check the index path retrieval method for a single item on a repeated item.
|
| + EXPECT_EQ(1, indexPath.section);
|
| + EXPECT_EQ(1, indexPath.item);
|
| +
|
| + // Check the index path retrieval method for a repeated item.
|
| + indexPath = [model indexPathForItemType:ItemTypeWeasleyArthur
|
| + sectionIdentifier:SectionIdentifierWeasley
|
| + atIndex:1];
|
| +
|
| + EXPECT_EQ(1, indexPath.section);
|
| + EXPECT_EQ(2, indexPath.item);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, RepeatedItemIndex) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheesePepperJack
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyGinny
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyGinny
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| +
|
| + // Check the index path <-> index in item type correspondance method.
|
| + EXPECT_EQ(
|
| + 0U, [model indexInItemTypeForIndexPath:[NSIndexPath indexPathForItem:0
|
| + inSection:0]]);
|
| + EXPECT_EQ(
|
| + 0U, [model indexInItemTypeForIndexPath:[NSIndexPath indexPathForItem:1
|
| + inSection:1]]);
|
| + EXPECT_EQ(
|
| + 2U, [model indexInItemTypeForIndexPath:[NSIndexPath indexPathForItem:3
|
| + inSection:1]]);
|
| + EXPECT_EQ(
|
| + 3U, [model indexInItemTypeForIndexPath:[NSIndexPath indexPathForItem:5
|
| + inSection:1]]);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, RetrieveAddedItem) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + base::scoped_nsobject<CollectionViewItem> someItem(
|
| + [[CollectionViewItem alloc] initWithType:ItemTypeCheeseGouda]);
|
| + [model addItem:someItem toSectionWithIdentifier:SectionIdentifierCheese];
|
| +
|
| + // Check that the item is the same in the model.
|
| + EXPECT_EQ(someItem, [model itemAtIndexPath:[NSIndexPath indexPathForItem:0
|
| + inSection:0]]);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, RetrieveItemsInSection) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + base::scoped_nsobject<CollectionViewItem> cheddar(
|
| + [[CollectionViewItem alloc] initWithType:ItemTypeCheeseCheddar]);
|
| + [model addItem:cheddar toSectionWithIdentifier:SectionIdentifierCheese];
|
| + base::scoped_nsobject<CollectionViewItem> pepperJack(
|
| + [[CollectionViewItem alloc] initWithType:ItemTypeCheesePepperJack]);
|
| + [model addItem:pepperJack toSectionWithIdentifier:SectionIdentifierCheese];
|
| + base::scoped_nsobject<CollectionViewItem> gouda(
|
| + [[CollectionViewItem alloc] initWithType:ItemTypeCheeseGouda]);
|
| + [model addItem:gouda toSectionWithIdentifier:SectionIdentifierCheese];
|
| +
|
| + NSArray* cheeseItems =
|
| + [model itemsInSectionWithIdentifier:SectionIdentifierCheese];
|
| + EXPECT_EQ(3U, [cheeseItems count]);
|
| + EXPECT_NSEQ(cheddar, cheeseItems[0]);
|
| + EXPECT_NSEQ(pepperJack, cheeseItems[1]);
|
| + EXPECT_NSEQ(gouda, cheeseItems[2]);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, InvalidIndexPath) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| +
|
| + bool out_of_bounds_exception_thrown = false;
|
| + @try {
|
| + logging::SetLogAssertHandler(&LogSink);
|
| + [model indexInItemTypeForIndexPath:[NSIndexPath indexPathForItem:0
|
| + inSection:0]];
|
| + } @catch (NSException* exception) {
|
| + if ([[exception name] isEqualToString:NSRangeException]) {
|
| + out_of_bounds_exception_thrown = true;
|
| + }
|
| + }
|
| + EXPECT_TRUE(out_of_bounds_exception_thrown);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, RemoveItems) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheesePepperJack
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheeseGouda
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyGinny
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyRon
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| +
|
| + [model removeItemWithType:ItemTypeCheesePepperJack
|
| + fromSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model removeItemWithType:ItemTypeWeasleyGinny
|
| + fromSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model removeItemWithType:ItemTypeWeasleyArthur
|
| + fromSectionWithIdentifier:SectionIdentifierWeasley
|
| + atIndex:2];
|
| +
|
| + // Check the collection view data sourcing methods.
|
| + EXPECT_EQ(2, [model numberOfSections]);
|
| +
|
| + // Check the index path retrieval method for a single item.
|
| + NSIndexPath* indexPath = [model indexPathForItemType:ItemTypeCheeseGouda
|
| + sectionIdentifier:SectionIdentifierCheese];
|
| + EXPECT_EQ(0, indexPath.section);
|
| + EXPECT_EQ(0, indexPath.item);
|
| +
|
| + // Check the index path retrieval method for a repeated item.
|
| + indexPath = [model indexPathForItemType:ItemTypeWeasleyArthur
|
| + sectionIdentifier:SectionIdentifierWeasley
|
| + atIndex:1];
|
| + EXPECT_EQ(1, indexPath.section);
|
| + EXPECT_EQ(1, indexPath.item);
|
| +
|
| + // Check the index path retrieval method for a single item.
|
| + indexPath = [model indexPathForItemType:ItemTypeWeasleyRon
|
| + sectionIdentifier:SectionIdentifierWeasley];
|
| + EXPECT_EQ(1, indexPath.section);
|
| + EXPECT_EQ(2, indexPath.item);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, RemoveSections) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + // Empty section.
|
| + [model addSectionWithIdentifier:SectionIdentifierWeasley];
|
| +
|
| + // Section with items.
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheesePepperJack
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheeseGouda
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| +
|
| + // Check the collection view data sourcing methods.
|
| + EXPECT_EQ(2, [model numberOfSections]);
|
| + EXPECT_EQ(0, [model numberOfItemsInSection:0]);
|
| + EXPECT_EQ(2, [model numberOfItemsInSection:1]);
|
| +
|
| + // Remove an empty section.
|
| + [model removeSectionWithIdentifier:SectionIdentifierWeasley];
|
| +
|
| + // Check that the section was removed.
|
| + EXPECT_EQ(1, [model numberOfSections]);
|
| + EXPECT_EQ(2, [model numberOfItemsInSection:0]);
|
| +
|
| + // Remove a section with items.
|
| + [model removeSectionWithIdentifier:SectionIdentifierCheese];
|
| +
|
| + // Check that the section and its items were removed.
|
| + EXPECT_EQ(0, [model numberOfSections]);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, QueryItemsFromModelCoordinates) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + EXPECT_FALSE([model hasSectionForSectionIdentifier:SectionIdentifierWeasley]);
|
| + EXPECT_FALSE([model hasItemForItemType:ItemTypeCheeseCheddar
|
| + sectionIdentifier:SectionIdentifierCheese]);
|
| + EXPECT_FALSE([model hasItemForItemType:ItemTypeCheeseGouda
|
| + sectionIdentifier:SectionIdentifierCheese
|
| + atIndex:1]);
|
| +
|
| + // Section with items.
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheesePepperJack
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheeseGouda
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheeseGouda
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| +
|
| + EXPECT_TRUE([model hasSectionForSectionIdentifier:SectionIdentifierCheese]);
|
| + EXPECT_FALSE([model hasItemForItemType:ItemTypeCheeseCheddar
|
| + sectionIdentifier:SectionIdentifierCheese]);
|
| + EXPECT_TRUE([model hasItemForItemType:ItemTypeCheesePepperJack
|
| + sectionIdentifier:SectionIdentifierCheese]);
|
| + EXPECT_TRUE([model hasItemForItemType:ItemTypeCheeseGouda
|
| + sectionIdentifier:SectionIdentifierCheese
|
| + atIndex:1]);
|
| +}
|
| +
|
| +// Tests that inserted sections are added at the correct index.
|
| +TEST(CollectionViewModelTest, InsertSections) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierWeasley];
|
| + EXPECT_EQ(1, [model numberOfSections]);
|
| + EXPECT_EQ(0, [model sectionForSectionIdentifier:SectionIdentifierWeasley]);
|
| +
|
| + [model insertSectionWithIdentifier:SectionIdentifierCheese atIndex:0];
|
| + EXPECT_EQ(2, [model numberOfSections]);
|
| + EXPECT_EQ(1, [model sectionForSectionIdentifier:SectionIdentifierWeasley]);
|
| + EXPECT_EQ(0, [model sectionForSectionIdentifier:SectionIdentifierCheese]);
|
| +
|
| + [model removeSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model insertSectionWithIdentifier:SectionIdentifierCheese atIndex:1];
|
| + EXPECT_EQ(2, [model numberOfSections]);
|
| + EXPECT_EQ(0, [model sectionForSectionIdentifier:SectionIdentifierWeasley]);
|
| + EXPECT_EQ(1, [model sectionForSectionIdentifier:SectionIdentifierCheese]);
|
| +}
|
| +
|
| +// Tests that inserted items are added at the correct index.
|
| +TEST(CollectionViewModelTest, InsertItemAtIndex) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheesePepperJack
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheeseGouda
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + base::scoped_nsobject<CollectionViewItem> cheddarItem(
|
| + [[CollectionViewItem alloc] initWithType:ItemTypeCheeseCheddar]);
|
| + [model insertItem:cheddarItem
|
| + inSectionWithIdentifier:SectionIdentifierCheese
|
| + atIndex:1];
|
| +
|
| + EXPECT_EQ(1, [model numberOfSections]);
|
| +
|
| + NSIndexPath* pepperJackIndexPath =
|
| + [model indexPathForItemType:ItemTypeCheesePepperJack
|
| + sectionIdentifier:SectionIdentifierCheese];
|
| + EXPECT_EQ(0, pepperJackIndexPath.section);
|
| + EXPECT_EQ(0, pepperJackIndexPath.item);
|
| +
|
| + NSIndexPath* cheddarIndexPath =
|
| + [model indexPathForItemType:ItemTypeCheeseCheddar
|
| + sectionIdentifier:SectionIdentifierCheese];
|
| + EXPECT_EQ(0, cheddarIndexPath.section);
|
| + EXPECT_EQ(1, cheddarIndexPath.item);
|
| +
|
| + NSIndexPath* goudaIndexPath =
|
| + [model indexPathForItemType:ItemTypeCheeseGouda
|
| + sectionIdentifier:SectionIdentifierCheese];
|
| + EXPECT_EQ(0, goudaIndexPath.section);
|
| + EXPECT_EQ(2, goudaIndexPath.item);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, IndexPathsForItems) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyGinny
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + // Added at index 1.
|
| + base::scoped_nsobject<CollectionViewItem> item1(
|
| + [[CollectionViewItem alloc] initWithType:ItemTypeWeasleyRon]);
|
| + [model addItem:item1 toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyGinny
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + // Repeated item added at index 4.
|
| + base::scoped_nsobject<CollectionViewItem> item4(
|
| + [[CollectionViewItem alloc] initWithType:ItemTypeWeasleyArthur]);
|
| + [model addItem:item4 toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyArthur
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| +
|
| + NSIndexPath* indexPath1 = [model indexPathForItem:item1
|
| + inSectionWithIdentifier:SectionIdentifierWeasley];
|
| + EXPECT_EQ(0, indexPath1.section);
|
| + EXPECT_EQ(1, indexPath1.item);
|
| +
|
| + NSIndexPath* indexPath4 = [model indexPathForItem:item4
|
| + inSectionWithIdentifier:SectionIdentifierWeasley];
|
| + EXPECT_EQ(0, indexPath4.section);
|
| + EXPECT_EQ(4, indexPath4.item);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, Headers) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + base::scoped_nsobject<CollectionViewItem> cheeseHeader(
|
| + [[CollectionViewItem alloc] initWithType:ItemTypeCheeseHeader]);
|
| + [model setHeader:cheeseHeader
|
| + forSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheeseGouda
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheeseCheddar
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyRon
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyGinny
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| +
|
| + NSInteger cheeseSection =
|
| + [model sectionForSectionIdentifier:SectionIdentifierCheese];
|
| + NSInteger weasleySection =
|
| + [model sectionForSectionIdentifier:SectionIdentifierWeasley];
|
| +
|
| + EXPECT_EQ(cheeseHeader.get(),
|
| + [model headerForSectionWithIdentifier:SectionIdentifierCheese]);
|
| + EXPECT_EQ(cheeseHeader.get(), [model headerForSection:cheeseSection]);
|
| +
|
| + EXPECT_FALSE([model headerForSectionWithIdentifier:SectionIdentifierWeasley]);
|
| + EXPECT_FALSE([model headerForSection:weasleySection]);
|
| +}
|
| +
|
| +TEST(CollectionViewModelTest, Footers) {
|
| + base::scoped_nsobject<CollectionViewModel> model(
|
| + [[CollectionViewModel alloc] init]);
|
| +
|
| + [model addSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheeseGouda
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addItemWithType:ItemTypeCheeseCheddar
|
| + toSectionWithIdentifier:SectionIdentifierCheese];
|
| + [model addSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyRon
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + [model addItemWithType:ItemTypeWeasleyGinny
|
| + toSectionWithIdentifier:SectionIdentifierWeasley];
|
| + base::scoped_nsobject<CollectionViewItem> weasleyFooter(
|
| + [[CollectionViewItem alloc] initWithType:ItemTypeWeasleyFooter]);
|
| + [model setFooter:weasleyFooter
|
| + forSectionWithIdentifier:SectionIdentifierWeasley];
|
| +
|
| + NSInteger cheeseSection =
|
| + [model sectionForSectionIdentifier:SectionIdentifierCheese];
|
| + NSInteger weasleySection =
|
| + [model sectionForSectionIdentifier:SectionIdentifierWeasley];
|
| +
|
| + EXPECT_FALSE([model footerForSectionWithIdentifier:SectionIdentifierCheese]);
|
| + EXPECT_FALSE([model footerForSection:cheeseSection]);
|
| +
|
| + EXPECT_EQ(weasleyFooter.get(),
|
| + [model footerForSectionWithIdentifier:SectionIdentifierWeasley]);
|
| + EXPECT_EQ(weasleyFooter.get(), [model footerForSection:weasleySection]);
|
| +}
|
| +
|
| +} // namespace
|
|
|