diff --git a/Example/Examples/Sources/Examples/ExampleList/ExampleListCoordinator+Presentable.swift b/Example/Examples/Sources/Examples/ExampleList/ExampleListCoordinator+Presentable.swift index 64f3caf8..136a4178 100644 --- a/Example/Examples/Sources/Examples/ExampleList/ExampleListCoordinator+Presentable.swift +++ b/Example/Examples/Sources/Examples/ExampleList/ExampleListCoordinator+Presentable.swift @@ -36,7 +36,15 @@ extension ExampleListCoordinator: Presentable { navigationController: navigationController, presentable: VanillaSwiftExamples.EmojisCoordinator(navigationController: navigationController) ) - ) + ), + ExampleViewModel( + name: "Names", + description: "An MVVM-C architecture with compositional layout example by using a ListCompositionalLayoutCollectionViewAdapter that shows multiple ListCompositionalLayoutSectionController.", + navigation: ExampleCoordinator( + navigationController: navigationController, + presentable: NamesCoordinator(navigationController: navigationController) + ) + ), ] ), ExampleSectionViewModel( diff --git a/Example/SectionKitExample.xcodeproj/project.pbxproj b/Example/SectionKitExample.xcodeproj/project.pbxproj index bf65b45d..11986291 100644 --- a/Example/SectionKitExample.xcodeproj/project.pbxproj +++ b/Example/SectionKitExample.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -12,6 +12,7 @@ 5AFBBE14264BEF2B008C095D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AFBBE13264BEF2B008C095D /* SceneDelegate.swift */; }; 5AFBBE18264BEF2C008C095D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5AFBBE17264BEF2C008C095D /* Assets.xcassets */; }; 5AFBBE1E264BEF2C008C095D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5AFBBE1C264BEF2C008C095D /* LaunchScreen.storyboard */; }; + D91425612BB478D90005E8CD /* first-names.json in Resources */ = {isa = PBXBuildFile; fileRef = D91425602BB478D90005E8CD /* first-names.json */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -27,6 +28,7 @@ 5AFBBE1F264BEF2C008C095D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5AFBBE25264BEF34008C095D /* tr-sectionkit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "tr-sectionkit"; path = ..; sourceTree = ""; }; 5AFBBE26264BEF41008C095D /* SectionKitExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SectionKitExample.entitlements; sourceTree = ""; }; + D91425602BB478D90005E8CD /* first-names.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "first-names.json"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -66,6 +68,7 @@ 5AFBBE10264BEF2B008C095D /* SectionKitExample */ = { isa = PBXGroup; children = ( + D914255F2BB478B60005E8CD /* Resources */, 5AFBBE11264BEF2B008C095D /* AppDelegate.swift */, 5AFBBE13264BEF2B008C095D /* SceneDelegate.swift */, 5AFBBE17264BEF2C008C095D /* Assets.xcassets */, @@ -83,6 +86,14 @@ name = Frameworks; sourceTree = ""; }; + D914255F2BB478B60005E8CD /* Resources */ = { + isa = PBXGroup; + children = ( + D91425602BB478D90005E8CD /* first-names.json */, + ); + path = Resources; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -146,6 +157,7 @@ buildActionMask = 2147483647; files = ( 5AFBBE1E264BEF2C008C095D /* LaunchScreen.storyboard in Resources */, + D91425612BB478D90005E8CD /* first-names.json in Resources */, 5AFBBE18264BEF2C008C095D /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Example/SectionKitExample/Resources/first-names.json b/Example/SectionKitExample/Resources/first-names.json new file mode 100644 index 00000000..580d1ac3 --- /dev/null +++ b/Example/SectionKitExample/Resources/first-names.json @@ -0,0 +1,9893 @@ +[ +"Aaren" +, +"Aarika" +, +"Abagael" +, +"Abagail" +, +"Abbe" +, +"Abbey" +, +"Abbi" +, +"Abbie" +, +"Abby" +, +"Abbye" +, +"Abigael" +, +"Abigail" +, +"Abigale" +, +"Abra" +, +"Ada" +, +"Adah" +, +"Adaline" +, +"Adan" +, +"Adara" +, +"Adda" +, +"Addi" +, +"Addia" +, +"Addie" +, +"Addy" +, +"Adel" +, +"Adela" +, +"Adelaida" +, +"Adelaide" +, +"Adele" +, +"Adelheid" +, +"Adelice" +, +"Adelina" +, +"Adelind" +, +"Adeline" +, +"Adella" +, +"Adelle" +, +"Adena" +, +"Adey" +, +"Adi" +, +"Adiana" +, +"Adina" +, +"Adora" +, +"Adore" +, +"Adoree" +, +"Adorne" +, +"Adrea" +, +"Adria" +, +"Adriaens" +, +"Adrian" +, +"Adriana" +, +"Adriane" +, +"Adrianna" +, +"Adrianne" +, +"Adriena" +, +"Adrienne" +, +"Aeriel" +, +"Aeriela" +, +"Aeriell" +, +"Afton" +, +"Ag" +, +"Agace" +, +"Agata" +, +"Agatha" +, +"Agathe" +, +"Aggi" +, +"Aggie" +, +"Aggy" +, +"Agna" +, +"Agnella" +, +"Agnes" +, +"Agnese" +, +"Agnesse" +, +"Agneta" +, +"Agnola" +, +"Agretha" +, +"Aida" +, +"Aidan" +, +"Aigneis" +, +"Aila" +, +"Aile" +, +"Ailee" +, +"Aileen" +, +"Ailene" +, +"Ailey" +, +"Aili" +, +"Ailina" +, +"Ailis" +, +"Ailsun" +, +"Ailyn" +, +"Aime" +, +"Aimee" +, +"Aimil" +, +"Aindrea" +, +"Ainslee" +, +"Ainsley" +, +"Ainslie" +, +"Ajay" +, +"Alaine" +, +"Alameda" +, +"Alana" +, +"Alanah" +, +"Alane" +, +"Alanna" +, +"Alayne" +, +"Alberta" +, +"Albertina" +, +"Albertine" +, +"Albina" +, +"Alecia" +, +"Aleda" +, +"Aleece" +, +"Aleen" +, +"Alejandra" +, +"Alejandrina" +, +"Alena" +, +"Alene" +, +"Alessandra" +, +"Aleta" +, +"Alethea" +, +"Alex" +, +"Alexa" +, +"Alexandra" +, +"Alexandrina" +, +"Alexi" +, +"Alexia" +, +"Alexina" +, +"Alexine" +, +"Alexis" +, +"Alfi" +, +"Alfie" +, +"Alfreda" +, +"Alfy" +, +"Ali" +, +"Alia" +, +"Alica" +, +"Alice" +, +"Alicea" +, +"Alicia" +, +"Alida" +, +"Alidia" +, +"Alie" +, +"Alika" +, +"Alikee" +, +"Alina" +, +"Aline" +, +"Alis" +, +"Alisa" +, +"Alisha" +, +"Alison" +, +"Alissa" +, +"Alisun" +, +"Alix" +, +"Aliza" +, +"Alla" +, +"Alleen" +, +"Allegra" +, +"Allene" +, +"Alli" +, +"Allianora" +, +"Allie" +, +"Allina" +, +"Allis" +, +"Allison" +, +"Allissa" +, +"Allix" +, +"Allsun" +, +"Allx" +, +"Ally" +, +"Allyce" +, +"Allyn" +, +"Allys" +, +"Allyson" +, +"Alma" +, +"Almeda" +, +"Almeria" +, +"Almeta" +, +"Almira" +, +"Almire" +, +"Aloise" +, +"Aloisia" +, +"Aloysia" +, +"Alta" +, +"Althea" +, +"Alvera" +, +"Alverta" +, +"Alvina" +, +"Alvinia" +, +"Alvira" +, +"Alyce" +, +"Alyda" +, +"Alys" +, +"Alysa" +, +"Alyse" +, +"Alysia" +, +"Alyson" +, +"Alyss" +, +"Alyssa" +, +"Amabel" +, +"Amabelle" +, +"Amalea" +, +"Amalee" +, +"Amaleta" +, +"Amalia" +, +"Amalie" +, +"Amalita" +, +"Amalle" +, +"Amanda" +, +"Amandi" +, +"Amandie" +, +"Amandy" +, +"Amara" +, +"Amargo" +, +"Amata" +, +"Amber" +, +"Amberly" +, +"Ambur" +, +"Ame" +, +"Amelia" +, +"Amelie" +, +"Amelina" +, +"Ameline" +, +"Amelita" +, +"Ami" +, +"Amie" +, +"Amii" +, +"Amil" +, +"Amitie" +, +"Amity" +, +"Ammamaria" +, +"Amy" +, +"Amye" +, +"Ana" +, +"Anabal" +, +"Anabel" +, +"Anabella" +, +"Anabelle" +, +"Analiese" +, +"Analise" +, +"Anallese" +, +"Anallise" +, +"Anastasia" +, +"Anastasie" +, +"Anastassia" +, +"Anatola" +, +"Andee" +, +"Andeee" +, +"Anderea" +, +"Andi" +, +"Andie" +, +"Andra" +, +"Andrea" +, +"Andreana" +, +"Andree" +, +"Andrei" +, +"Andria" +, +"Andriana" +, +"Andriette" +, +"Andromache" +, +"Andy" +, +"Anestassia" +, +"Anet" +, +"Anett" +, +"Anetta" +, +"Anette" +, +"Ange" +, +"Angel" +, +"Angela" +, +"Angele" +, +"Angelia" +, +"Angelica" +, +"Angelika" +, +"Angelina" +, +"Angeline" +, +"Angelique" +, +"Angelita" +, +"Angelle" +, +"Angie" +, +"Angil" +, +"Angy" +, +"Ania" +, +"Anica" +, +"Anissa" +, +"Anita" +, +"Anitra" +, +"Anjanette" +, +"Anjela" +, +"Ann" +, +"Ann-Marie" +, +"Anna" +, +"Anna-Diana" +, +"Anna-Diane" +, +"Anna-Maria" +, +"Annabal" +, +"Annabel" +, +"Annabela" +, +"Annabell" +, +"Annabella" +, +"Annabelle" +, +"Annadiana" +, +"Annadiane" +, +"Annalee" +, +"Annaliese" +, +"Annalise" +, +"Annamaria" +, +"Annamarie" +, +"Anne" +, +"Anne-Corinne" +, +"Anne-Marie" +, +"Annecorinne" +, +"Anneliese" +, +"Annelise" +, +"Annemarie" +, +"Annetta" +, +"Annette" +, +"Anni" +, +"Annice" +, +"Annie" +, +"Annis" +, +"Annissa" +, +"Annmaria" +, +"Annmarie" +, +"Annnora" +, +"Annora" +, +"Anny" +, +"Anselma" +, +"Ansley" +, +"Anstice" +, +"Anthe" +, +"Anthea" +, +"Anthia" +, +"Anthiathia" +, +"Antoinette" +, +"Antonella" +, +"Antonetta" +, +"Antonia" +, +"Antonie" +, +"Antonietta" +, +"Antonina" +, +"Anya" +, +"Appolonia" +, +"April" +, +"Aprilette" +, +"Ara" +, +"Arabel" +, +"Arabela" +, +"Arabele" +, +"Arabella" +, +"Arabelle" +, +"Arda" +, +"Ardath" +, +"Ardeen" +, +"Ardelia" +, +"Ardelis" +, +"Ardella" +, +"Ardelle" +, +"Arden" +, +"Ardene" +, +"Ardenia" +, +"Ardine" +, +"Ardis" +, +"Ardisj" +, +"Ardith" +, +"Ardra" +, +"Ardyce" +, +"Ardys" +, +"Ardyth" +, +"Aretha" +, +"Ariadne" +, +"Ariana" +, +"Aridatha" +, +"Ariel" +, +"Ariela" +, +"Ariella" +, +"Arielle" +, +"Arlana" +, +"Arlee" +, +"Arleen" +, +"Arlen" +, +"Arlena" +, +"Arlene" +, +"Arleta" +, +"Arlette" +, +"Arleyne" +, +"Arlie" +, +"Arliene" +, +"Arlina" +, +"Arlinda" +, +"Arline" +, +"Arluene" +, +"Arly" +, +"Arlyn" +, +"Arlyne" +, +"Aryn" +, +"Ashely" +, +"Ashia" +, +"Ashien" +, +"Ashil" +, +"Ashla" +, +"Ashlan" +, +"Ashlee" +, +"Ashleigh" +, +"Ashlen" +, +"Ashley" +, +"Ashli" +, +"Ashlie" +, +"Ashly" +, +"Asia" +, +"Astra" +, +"Astrid" +, +"Astrix" +, +"Atalanta" +, +"Athena" +, +"Athene" +, +"Atlanta" +, +"Atlante" +, +"Auberta" +, +"Aubine" +, +"Aubree" +, +"Aubrette" +, +"Aubrey" +, +"Aubrie" +, +"Aubry" +, +"Audi" +, +"Audie" +, +"Audra" +, +"Audre" +, +"Audrey" +, +"Audrie" +, +"Audry" +, +"Audrye" +, +"Audy" +, +"Augusta" +, +"Auguste" +, +"Augustina" +, +"Augustine" +, +"Aundrea" +, +"Aura" +, +"Aurea" +, +"Aurel" +, +"Aurelea" +, +"Aurelia" +, +"Aurelie" +, +"Auria" +, +"Aurie" +, +"Aurilia" +, +"Aurlie" +, +"Auroora" +, +"Aurora" +, +"Aurore" +, +"Austin" +, +"Austina" +, +"Austine" +, +"Ava" +, +"Aveline" +, +"Averil" +, +"Averyl" +, +"Avie" +, +"Avis" +, +"Aviva" +, +"Avivah" +, +"Avril" +, +"Avrit" +, +"Ayn" +, +"Bab" +, +"Babara" +, +"Babb" +, +"Babbette" +, +"Babbie" +, +"Babette" +, +"Babita" +, +"Babs" +, +"Bambi" +, +"Bambie" +, +"Bamby" +, +"Barb" +, +"Barbabra" +, +"Barbara" +, +"Barbara-Anne" +, +"Barbaraanne" +, +"Barbe" +, +"Barbee" +, +"Barbette" +, +"Barbey" +, +"Barbi" +, +"Barbie" +, +"Barbra" +, +"Barby" +, +"Bari" +, +"Barrie" +, +"Barry" +, +"Basia" +, +"Bathsheba" +, +"Batsheva" +, +"Bea" +, +"Beatrice" +, +"Beatrisa" +, +"Beatrix" +, +"Beatriz" +, +"Bebe" +, +"Becca" +, +"Becka" +, +"Becki" +, +"Beckie" +, +"Becky" +, +"Bee" +, +"Beilul" +, +"Beitris" +, +"Bekki" +, +"Bel" +, +"Belia" +, +"Belicia" +, +"Belinda" +, +"Belita" +, +"Bell" +, +"Bella" +, +"Bellanca" +, +"Belle" +, +"Bellina" +, +"Belva" +, +"Belvia" +, +"Bendite" +, +"Benedetta" +, +"Benedicta" +, +"Benedikta" +, +"Benetta" +, +"Benita" +, +"Benni" +, +"Bennie" +, +"Benny" +, +"Benoite" +, +"Berenice" +, +"Beret" +, +"Berget" +, +"Berna" +, +"Bernadene" +, +"Bernadette" +, +"Bernadina" +, +"Bernadine" +, +"Bernardina" +, +"Bernardine" +, +"Bernelle" +, +"Bernete" +, +"Bernetta" +, +"Bernette" +, +"Berni" +, +"Bernice" +, +"Bernie" +, +"Bernita" +, +"Berny" +, +"Berri" +, +"Berrie" +, +"Berry" +, +"Bert" +, +"Berta" +, +"Berte" +, +"Bertha" +, +"Berthe" +, +"Berti" +, +"Bertie" +, +"Bertina" +, +"Bertine" +, +"Berty" +, +"Beryl" +, +"Beryle" +, +"Bess" +, +"Bessie" +, +"Bessy" +, +"Beth" +, +"Bethanne" +, +"Bethany" +, +"Bethena" +, +"Bethina" +, +"Betsey" +, +"Betsy" +, +"Betta" +, +"Bette" +, +"Bette-Ann" +, +"Betteann" +, +"Betteanne" +, +"Betti" +, +"Bettina" +, +"Bettine" +, +"Betty" +, +"Bettye" +, +"Beulah" +, +"Bev" +, +"Beverie" +, +"Beverlee" +, +"Beverley" +, +"Beverlie" +, +"Beverly" +, +"Bevvy" +, +"Bianca" +, +"Bianka" +, +"Bibbie" +, +"Bibby" +, +"Bibbye" +, +"Bibi" +, +"Biddie" +, +"Biddy" +, +"Bidget" +, +"Bili" +, +"Bill" +, +"Billi" +, +"Billie" +, +"Billy" +, +"Billye" +, +"Binni" +, +"Binnie" +, +"Binny" +, +"Bird" +, +"Birdie" +, +"Birgit" +, +"Birgitta" +, +"Blair" +, +"Blaire" +, +"Blake" +, +"Blakelee" +, +"Blakeley" +, +"Blanca" +, +"Blanch" +, +"Blancha" +, +"Blanche" +, +"Blinni" +, +"Blinnie" +, +"Blinny" +, +"Bliss" +, +"Blisse" +, +"Blithe" +, +"Blondell" +, +"Blondelle" +, +"Blondie" +, +"Blondy" +, +"Blythe" +, +"Bobbe" +, +"Bobbee" +, +"Bobbette" +, +"Bobbi" +, +"Bobbie" +, +"Bobby" +, +"Bobbye" +, +"Bobette" +, +"Bobina" +, +"Bobine" +, +"Bobinette" +, +"Bonita" +, +"Bonnee" +, +"Bonni" +, +"Bonnibelle" +, +"Bonnie" +, +"Bonny" +, +"Brana" +, +"Brandais" +, +"Brande" +, +"Brandea" +, +"Brandi" +, +"Brandice" +, +"Brandie" +, +"Brandise" +, +"Brandy" +, +"Breanne" +, +"Brear" +, +"Bree" +, +"Breena" +, +"Bren" +, +"Brena" +, +"Brenda" +, +"Brenn" +, +"Brenna" +, +"Brett" +, +"Bria" +, +"Briana" +, +"Brianna" +, +"Brianne" +, +"Bride" +, +"Bridget" +, +"Bridgette" +, +"Bridie" +, +"Brier" +, +"Brietta" +, +"Brigid" +, +"Brigida" +, +"Brigit" +, +"Brigitta" +, +"Brigitte" +, +"Brina" +, +"Briney" +, +"Brinn" +, +"Brinna" +, +"Briny" +, +"Brit" +, +"Brita" +, +"Britney" +, +"Britni" +, +"Britt" +, +"Britta" +, +"Brittan" +, +"Brittaney" +, +"Brittani" +, +"Brittany" +, +"Britte" +, +"Britteny" +, +"Brittne" +, +"Brittney" +, +"Brittni" +, +"Brook" +, +"Brooke" +, +"Brooks" +, +"Brunhilda" +, +"Brunhilde" +, +"Bryana" +, +"Bryn" +, +"Bryna" +, +"Brynn" +, +"Brynna" +, +"Brynne" +, +"Buffy" +, +"Bunni" +, +"Bunnie" +, +"Bunny" +, +"Cacilia" +, +"Cacilie" +, +"Cahra" +, +"Cairistiona" +, +"Caitlin" +, +"Caitrin" +, +"Cal" +, +"Calida" +, +"Calla" +, +"Calley" +, +"Calli" +, +"Callida" +, +"Callie" +, +"Cally" +, +"Calypso" +, +"Cam" +, +"Camala" +, +"Camel" +, +"Camella" +, +"Camellia" +, +"Cami" +, +"Camila" +, +"Camile" +, +"Camilla" +, +"Camille" +, +"Cammi" +, +"Cammie" +, +"Cammy" +, +"Candace" +, +"Candi" +, +"Candice" +, +"Candida" +, +"Candide" +, +"Candie" +, +"Candis" +, +"Candra" +, +"Candy" +, +"Caprice" +, +"Cara" +, +"Caralie" +, +"Caren" +, +"Carena" +, +"Caresa" +, +"Caressa" +, +"Caresse" +, +"Carey" +, +"Cari" +, +"Caria" +, +"Carie" +, +"Caril" +, +"Carilyn" +, +"Carin" +, +"Carina" +, +"Carine" +, +"Cariotta" +, +"Carissa" +, +"Carita" +, +"Caritta" +, +"Carla" +, +"Carlee" +, +"Carleen" +, +"Carlen" +, +"Carlene" +, +"Carley" +, +"Carlie" +, +"Carlin" +, +"Carlina" +, +"Carline" +, +"Carlita" +, +"Carlota" +, +"Carlotta" +, +"Carly" +, +"Carlye" +, +"Carlyn" +, +"Carlynn" +, +"Carlynne" +, +"Carma" +, +"Carmel" +, +"Carmela" +, +"Carmelia" +, +"Carmelina" +, +"Carmelita" +, +"Carmella" +, +"Carmelle" +, +"Carmen" +, +"Carmencita" +, +"Carmina" +, +"Carmine" +, +"Carmita" +, +"Carmon" +, +"Caro" +, +"Carol" +, +"Carol-Jean" +, +"Carola" +, +"Carolan" +, +"Carolann" +, +"Carole" +, +"Carolee" +, +"Carolin" +, +"Carolina" +, +"Caroline" +, +"Caroljean" +, +"Carolyn" +, +"Carolyne" +, +"Carolynn" +, +"Caron" +, +"Carree" +, +"Carri" +, +"Carrie" +, +"Carrissa" +, +"Carroll" +, +"Carry" +, +"Cary" +, +"Caryl" +, +"Caryn" +, +"Casandra" +, +"Casey" +, +"Casi" +, +"Casie" +, +"Cass" +, +"Cassandra" +, +"Cassandre" +, +"Cassandry" +, +"Cassaundra" +, +"Cassey" +, +"Cassi" +, +"Cassie" +, +"Cassondra" +, +"Cassy" +, +"Catarina" +, +"Cate" +, +"Caterina" +, +"Catha" +, +"Catharina" +, +"Catharine" +, +"Cathe" +, +"Cathee" +, +"Catherin" +, +"Catherina" +, +"Catherine" +, +"Cathi" +, +"Cathie" +, +"Cathleen" +, +"Cathlene" +, +"Cathrin" +, +"Cathrine" +, +"Cathryn" +, +"Cathy" +, +"Cathyleen" +, +"Cati" +, +"Catie" +, +"Catina" +, +"Catlaina" +, +"Catlee" +, +"Catlin" +, +"Catrina" +, +"Catriona" +, +"Caty" +, +"Caye" +, +"Cayla" +, +"Cecelia" +, +"Cecil" +, +"Cecile" +, +"Ceciley" +, +"Cecilia" +, +"Cecilla" +, +"Cecily" +, +"Ceil" +, +"Cele" +, +"Celene" +, +"Celesta" +, +"Celeste" +, +"Celestia" +, +"Celestina" +, +"Celestine" +, +"Celestyn" +, +"Celestyna" +, +"Celia" +, +"Celie" +, +"Celina" +, +"Celinda" +, +"Celine" +, +"Celinka" +, +"Celisse" +, +"Celka" +, +"Celle" +, +"Cesya" +, +"Chad" +, +"Chanda" +, +"Chandal" +, +"Chandra" +, +"Channa" +, +"Chantal" +, +"Chantalle" +, +"Charil" +, +"Charin" +, +"Charis" +, +"Charissa" +, +"Charisse" +, +"Charita" +, +"Charity" +, +"Charla" +, +"Charlean" +, +"Charleen" +, +"Charlena" +, +"Charlene" +, +"Charline" +, +"Charlot" +, +"Charlotta" +, +"Charlotte" +, +"Charmain" +, +"Charmaine" +, +"Charmane" +, +"Charmian" +, +"Charmine" +, +"Charmion" +, +"Charo" +, +"Charyl" +, +"Chastity" +, +"Chelsae" +, +"Chelsea" +, +"Chelsey" +, +"Chelsie" +, +"Chelsy" +, +"Cher" +, +"Chere" +, +"Cherey" +, +"Cheri" +, +"Cherianne" +, +"Cherice" +, +"Cherida" +, +"Cherie" +, +"Cherilyn" +, +"Cherilynn" +, +"Cherin" +, +"Cherise" +, +"Cherish" +, +"Cherlyn" +, +"Cherri" +, +"Cherrita" +, +"Cherry" +, +"Chery" +, +"Cherye" +, +"Cheryl" +, +"Cheslie" +, +"Chiarra" +, +"Chickie" +, +"Chicky" +, +"Chiquia" +, +"Chiquita" +, +"Chlo" +, +"Chloe" +, +"Chloette" +, +"Chloris" +, +"Chris" +, +"Chrissie" +, +"Chrissy" +, +"Christa" +, +"Christabel" +, +"Christabella" +, +"Christal" +, +"Christalle" +, +"Christan" +, +"Christean" +, +"Christel" +, +"Christen" +, +"Christi" +, +"Christian" +, +"Christiana" +, +"Christiane" +, +"Christie" +, +"Christin" +, +"Christina" +, +"Christine" +, +"Christy" +, +"Christye" +, +"Christyna" +, +"Chrysa" +, +"Chrysler" +, +"Chrystal" +, +"Chryste" +, +"Chrystel" +, +"Cicely" +, +"Cicily" +, +"Ciel" +, +"Cilka" +, +"Cinda" +, +"Cindee" +, +"Cindelyn" +, +"Cinderella" +, +"Cindi" +, +"Cindie" +, +"Cindra" +, +"Cindy" +, +"Cinnamon" +, +"Cissiee" +, +"Cissy" +, +"Clair" +, +"Claire" +, +"Clara" +, +"Clarabelle" +, +"Clare" +, +"Claresta" +, +"Clareta" +, +"Claretta" +, +"Clarette" +, +"Clarey" +, +"Clari" +, +"Claribel" +, +"Clarice" +, +"Clarie" +, +"Clarinda" +, +"Clarine" +, +"Clarissa" +, +"Clarisse" +, +"Clarita" +, +"Clary" +, +"Claude" +, +"Claudelle" +, +"Claudetta" +, +"Claudette" +, +"Claudia" +, +"Claudie" +, +"Claudina" +, +"Claudine" +, +"Clea" +, +"Clem" +, +"Clemence" +, +"Clementia" +, +"Clementina" +, +"Clementine" +, +"Clemmie" +, +"Clemmy" +, +"Cleo" +, +"Cleopatra" +, +"Clerissa" +, +"Clio" +, +"Clo" +, +"Cloe" +, +"Cloris" +, +"Clotilda" +, +"Clovis" +, +"Codee" +, +"Codi" +, +"Codie" +, +"Cody" +, +"Coleen" +, +"Colene" +, +"Coletta" +, +"Colette" +, +"Colleen" +, +"Collen" +, +"Collete" +, +"Collette" +, +"Collie" +, +"Colline" +, +"Colly" +, +"Con" +, +"Concettina" +, +"Conchita" +, +"Concordia" +, +"Conni" +, +"Connie" +, +"Conny" +, +"Consolata" +, +"Constance" +, +"Constancia" +, +"Constancy" +, +"Constanta" +, +"Constantia" +, +"Constantina" +, +"Constantine" +, +"Consuela" +, +"Consuelo" +, +"Cookie" +, +"Cora" +, +"Corabel" +, +"Corabella" +, +"Corabelle" +, +"Coral" +, +"Coralie" +, +"Coraline" +, +"Coralyn" +, +"Cordelia" +, +"Cordelie" +, +"Cordey" +, +"Cordi" +, +"Cordie" +, +"Cordula" +, +"Cordy" +, +"Coreen" +, +"Corella" +, +"Corenda" +, +"Corene" +, +"Coretta" +, +"Corette" +, +"Corey" +, +"Cori" +, +"Corie" +, +"Corilla" +, +"Corina" +, +"Corine" +, +"Corinna" +, +"Corinne" +, +"Coriss" +, +"Corissa" +, +"Corliss" +, +"Corly" +, +"Cornela" +, +"Cornelia" +, +"Cornelle" +, +"Cornie" +, +"Corny" +, +"Correna" +, +"Correy" +, +"Corri" +, +"Corrianne" +, +"Corrie" +, +"Corrina" +, +"Corrine" +, +"Corrinne" +, +"Corry" +, +"Cortney" +, +"Cory" +, +"Cosetta" +, +"Cosette" +, +"Costanza" +, +"Courtenay" +, +"Courtnay" +, +"Courtney" +, +"Crin" +, +"Cris" +, +"Crissie" +, +"Crissy" +, +"Crista" +, +"Cristabel" +, +"Cristal" +, +"Cristen" +, +"Cristi" +, +"Cristie" +, +"Cristin" +, +"Cristina" +, +"Cristine" +, +"Cristionna" +, +"Cristy" +, +"Crysta" +, +"Crystal" +, +"Crystie" +, +"Cthrine" +, +"Cyb" +, +"Cybil" +, +"Cybill" +, +"Cymbre" +, +"Cynde" +, +"Cyndi" +, +"Cyndia" +, +"Cyndie" +, +"Cyndy" +, +"Cynthea" +, +"Cynthia" +, +"Cynthie" +, +"Cynthy" +, +"Dacey" +, +"Dacia" +, +"Dacie" +, +"Dacy" +, +"Dael" +, +"Daffi" +, +"Daffie" +, +"Daffy" +, +"Dagmar" +, +"Dahlia" +, +"Daile" +, +"Daisey" +, +"Daisi" +, +"Daisie" +, +"Daisy" +, +"Dale" +, +"Dalenna" +, +"Dalia" +, +"Dalila" +, +"Dallas" +, +"Daloris" +, +"Damara" +, +"Damaris" +, +"Damita" +, +"Dana" +, +"Danell" +, +"Danella" +, +"Danette" +, +"Dani" +, +"Dania" +, +"Danica" +, +"Danice" +, +"Daniela" +, +"Daniele" +, +"Daniella" +, +"Danielle" +, +"Danika" +, +"Danila" +, +"Danit" +, +"Danita" +, +"Danna" +, +"Danni" +, +"Dannie" +, +"Danny" +, +"Dannye" +, +"Danya" +, +"Danyelle" +, +"Danyette" +, +"Daphene" +, +"Daphna" +, +"Daphne" +, +"Dara" +, +"Darb" +, +"Darbie" +, +"Darby" +, +"Darcee" +, +"Darcey" +, +"Darci" +, +"Darcie" +, +"Darcy" +, +"Darda" +, +"Dareen" +, +"Darell" +, +"Darelle" +, +"Dari" +, +"Daria" +, +"Darice" +, +"Darla" +, +"Darleen" +, +"Darlene" +, +"Darline" +, +"Darlleen" +, +"Daron" +, +"Darrelle" +, +"Darryl" +, +"Darsey" +, +"Darsie" +, +"Darya" +, +"Daryl" +, +"Daryn" +, +"Dasha" +, +"Dasi" +, +"Dasie" +, +"Dasya" +, +"Datha" +, +"Daune" +, +"Daveen" +, +"Daveta" +, +"Davida" +, +"Davina" +, +"Davine" +, +"Davita" +, +"Dawn" +, +"Dawna" +, +"Dayle" +, +"Dayna" +, +"Ddene" +, +"De" +, +"Deana" +, +"Deane" +, +"Deanna" +, +"Deanne" +, +"Deb" +, +"Debbi" +, +"Debbie" +, +"Debby" +, +"Debee" +, +"Debera" +, +"Debi" +, +"Debor" +, +"Debora" +, +"Deborah" +, +"Debra" +, +"Dede" +, +"Dedie" +, +"Dedra" +, +"Dee" +, +"Dee Dee" +, +"Deeann" +, +"Deeanne" +, +"Deedee" +, +"Deena" +, +"Deerdre" +, +"Deeyn" +, +"Dehlia" +, +"Deidre" +, +"Deina" +, +"Deirdre" +, +"Del" +, +"Dela" +, +"Delcina" +, +"Delcine" +, +"Delia" +, +"Delila" +, +"Delilah" +, +"Delinda" +, +"Dell" +, +"Della" +, +"Delly" +, +"Delora" +, +"Delores" +, +"Deloria" +, +"Deloris" +, +"Delphine" +, +"Delphinia" +, +"Demeter" +, +"Demetra" +, +"Demetria" +, +"Demetris" +, +"Dena" +, +"Deni" +, +"Denice" +, +"Denise" +, +"Denna" +, +"Denni" +, +"Dennie" +, +"Denny" +, +"Deny" +, +"Denys" +, +"Denyse" +, +"Deonne" +, +"Desdemona" +, +"Desirae" +, +"Desiree" +, +"Desiri" +, +"Deva" +, +"Devan" +, +"Devi" +, +"Devin" +, +"Devina" +, +"Devinne" +, +"Devon" +, +"Devondra" +, +"Devonna" +, +"Devonne" +, +"Devora" +, +"Di" +, +"Diahann" +, +"Dian" +, +"Diana" +, +"Diandra" +, +"Diane" +, +"Diane-Marie" +, +"Dianemarie" +, +"Diann" +, +"Dianna" +, +"Dianne" +, +"Diannne" +, +"Didi" +, +"Dido" +, +"Diena" +, +"Dierdre" +, +"Dina" +, +"Dinah" +, +"Dinnie" +, +"Dinny" +, +"Dion" +, +"Dione" +, +"Dionis" +, +"Dionne" +, +"Dita" +, +"Dix" +, +"Dixie" +, +"Dniren" +, +"Dode" +, +"Dodi" +, +"Dodie" +, +"Dody" +, +"Doe" +, +"Doll" +, +"Dolley" +, +"Dolli" +, +"Dollie" +, +"Dolly" +, +"Dolores" +, +"Dolorita" +, +"Doloritas" +, +"Domeniga" +, +"Dominga" +, +"Domini" +, +"Dominica" +, +"Dominique" +, +"Dona" +, +"Donella" +, +"Donelle" +, +"Donetta" +, +"Donia" +, +"Donica" +, +"Donielle" +, +"Donna" +, +"Donnamarie" +, +"Donni" +, +"Donnie" +, +"Donny" +, +"Dora" +, +"Doralia" +, +"Doralin" +, +"Doralyn" +, +"Doralynn" +, +"Doralynne" +, +"Dore" +, +"Doreen" +, +"Dorelia" +, +"Dorella" +, +"Dorelle" +, +"Dorena" +, +"Dorene" +, +"Doretta" +, +"Dorette" +, +"Dorey" +, +"Dori" +, +"Doria" +, +"Dorian" +, +"Dorice" +, +"Dorie" +, +"Dorine" +, +"Doris" +, +"Dorisa" +, +"Dorise" +, +"Dorita" +, +"Doro" +, +"Dorolice" +, +"Dorolisa" +, +"Dorotea" +, +"Doroteya" +, +"Dorothea" +, +"Dorothee" +, +"Dorothy" +, +"Dorree" +, +"Dorri" +, +"Dorrie" +, +"Dorris" +, +"Dorry" +, +"Dorthea" +, +"Dorthy" +, +"Dory" +, +"Dosi" +, +"Dot" +, +"Doti" +, +"Dotti" +, +"Dottie" +, +"Dotty" +, +"Dre" +, +"Dreddy" +, +"Dredi" +, +"Drona" +, +"Dru" +, +"Druci" +, +"Drucie" +, +"Drucill" +, +"Drucy" +, +"Drusi" +, +"Drusie" +, +"Drusilla" +, +"Drusy" +, +"Dulce" +, +"Dulcea" +, +"Dulci" +, +"Dulcia" +, +"Dulciana" +, +"Dulcie" +, +"Dulcine" +, +"Dulcinea" +, +"Dulcy" +, +"Dulsea" +, +"Dusty" +, +"Dyan" +, +"Dyana" +, +"Dyane" +, +"Dyann" +, +"Dyanna" +, +"Dyanne" +, +"Dyna" +, +"Dynah" +, +"Eachelle" +, +"Eada" +, +"Eadie" +, +"Eadith" +, +"Ealasaid" +, +"Eartha" +, +"Easter" +, +"Eba" +, +"Ebba" +, +"Ebonee" +, +"Ebony" +, +"Eda" +, +"Eddi" +, +"Eddie" +, +"Eddy" +, +"Ede" +, +"Edee" +, +"Edeline" +, +"Eden" +, +"Edi" +, +"Edie" +, +"Edin" +, +"Edita" +, +"Edith" +, +"Editha" +, +"Edithe" +, +"Ediva" +, +"Edna" +, +"Edwina" +, +"Edy" +, +"Edyth" +, +"Edythe" +, +"Effie" +, +"Eileen" +, +"Eilis" +, +"Eimile" +, +"Eirena" +, +"Ekaterina" +, +"Elaina" +, +"Elaine" +, +"Elana" +, +"Elane" +, +"Elayne" +, +"Elberta" +, +"Elbertina" +, +"Elbertine" +, +"Eleanor" +, +"Eleanora" +, +"Eleanore" +, +"Electra" +, +"Eleen" +, +"Elena" +, +"Elene" +, +"Eleni" +, +"Elenore" +, +"Eleonora" +, +"Eleonore" +, +"Elfie" +, +"Elfreda" +, +"Elfrida" +, +"Elfrieda" +, +"Elga" +, +"Elianora" +, +"Elianore" +, +"Elicia" +, +"Elie" +, +"Elinor" +, +"Elinore" +, +"Elisa" +, +"Elisabet" +, +"Elisabeth" +, +"Elisabetta" +, +"Elise" +, +"Elisha" +, +"Elissa" +, +"Elita" +, +"Eliza" +, +"Elizabet" +, +"Elizabeth" +, +"Elka" +, +"Elke" +, +"Ella" +, +"Elladine" +, +"Elle" +, +"Ellen" +, +"Ellene" +, +"Ellette" +, +"Elli" +, +"Ellie" +, +"Ellissa" +, +"Elly" +, +"Ellyn" +, +"Ellynn" +, +"Elmira" +, +"Elna" +, +"Elnora" +, +"Elnore" +, +"Eloisa" +, +"Eloise" +, +"Elonore" +, +"Elora" +, +"Elsa" +, +"Elsbeth" +, +"Else" +, +"Elset" +, +"Elsey" +, +"Elsi" +, +"Elsie" +, +"Elsinore" +, +"Elspeth" +, +"Elsy" +, +"Elva" +, +"Elvera" +, +"Elvina" +, +"Elvira" +, +"Elwira" +, +"Elyn" +, +"Elyse" +, +"Elysee" +, +"Elysha" +, +"Elysia" +, +"Elyssa" +, +"Em" +, +"Ema" +, +"Emalee" +, +"Emalia" +, +"Emelda" +, +"Emelia" +, +"Emelina" +, +"Emeline" +, +"Emelita" +, +"Emelyne" +, +"Emera" +, +"Emilee" +, +"Emili" +, +"Emilia" +, +"Emilie" +, +"Emiline" +, +"Emily" +, +"Emlyn" +, +"Emlynn" +, +"Emlynne" +, +"Emma" +, +"Emmalee" +, +"Emmaline" +, +"Emmalyn" +, +"Emmalynn" +, +"Emmalynne" +, +"Emmeline" +, +"Emmey" +, +"Emmi" +, +"Emmie" +, +"Emmy" +, +"Emmye" +, +"Emogene" +, +"Emyle" +, +"Emylee" +, +"Engracia" +, +"Enid" +, +"Enrica" +, +"Enrichetta" +, +"Enrika" +, +"Enriqueta" +, +"Eolanda" +, +"Eolande" +, +"Eran" +, +"Erda" +, +"Erena" +, +"Erica" +, +"Ericha" +, +"Ericka" +, +"Erika" +, +"Erin" +, +"Erina" +, +"Erinn" +, +"Erinna" +, +"Erma" +, +"Ermengarde" +, +"Ermentrude" +, +"Ermina" +, +"Erminia" +, +"Erminie" +, +"Erna" +, +"Ernaline" +, +"Ernesta" +, +"Ernestine" +, +"Ertha" +, +"Eryn" +, +"Esma" +, +"Esmaria" +, +"Esme" +, +"Esmeralda" +, +"Essa" +, +"Essie" +, +"Essy" +, +"Esta" +, +"Estel" +, +"Estele" +, +"Estell" +, +"Estella" +, +"Estelle" +, +"Ester" +, +"Esther" +, +"Estrella" +, +"Estrellita" +, +"Ethel" +, +"Ethelda" +, +"Ethelin" +, +"Ethelind" +, +"Etheline" +, +"Ethelyn" +, +"Ethyl" +, +"Etta" +, +"Etti" +, +"Ettie" +, +"Etty" +, +"Eudora" +, +"Eugenia" +, +"Eugenie" +, +"Eugine" +, +"Eula" +, +"Eulalie" +, +"Eunice" +, +"Euphemia" +, +"Eustacia" +, +"Eva" +, +"Evaleen" +, +"Evangelia" +, +"Evangelin" +, +"Evangelina" +, +"Evangeline" +, +"Evania" +, +"Evanne" +, +"Eve" +, +"Eveleen" +, +"Evelina" +, +"Eveline" +, +"Evelyn" +, +"Evey" +, +"Evie" +, +"Evita" +, +"Evonne" +, +"Evvie" +, +"Evvy" +, +"Evy" +, +"Eyde" +, +"Eydie" +, +"Ezmeralda" +, +"Fae" +, +"Faina" +, +"Faith" +, +"Fallon" +, +"Fan" +, +"Fanchette" +, +"Fanchon" +, +"Fancie" +, +"Fancy" +, +"Fanechka" +, +"Fania" +, +"Fanni" +, +"Fannie" +, +"Fanny" +, +"Fanya" +, +"Fara" +, +"Farah" +, +"Farand" +, +"Farica" +, +"Farra" +, +"Farrah" +, +"Farrand" +, +"Faun" +, +"Faunie" +, +"Faustina" +, +"Faustine" +, +"Fawn" +, +"Fawne" +, +"Fawnia" +, +"Fay" +, +"Faydra" +, +"Faye" +, +"Fayette" +, +"Fayina" +, +"Fayre" +, +"Fayth" +, +"Faythe" +, +"Federica" +, +"Fedora" +, +"Felecia" +, +"Felicdad" +, +"Felice" +, +"Felicia" +, +"Felicity" +, +"Felicle" +, +"Felipa" +, +"Felisha" +, +"Felita" +, +"Feliza" +, +"Fenelia" +, +"Feodora" +, +"Ferdinanda" +, +"Ferdinande" +, +"Fern" +, +"Fernanda" +, +"Fernande" +, +"Fernandina" +, +"Ferne" +, +"Fey" +, +"Fiann" +, +"Fianna" +, +"Fidela" +, +"Fidelia" +, +"Fidelity" +, +"Fifi" +, +"Fifine" +, +"Filia" +, +"Filide" +, +"Filippa" +, +"Fina" +, +"Fiona" +, +"Fionna" +, +"Fionnula" +, +"Fiorenze" +, +"Fleur" +, +"Fleurette" +, +"Flo" +, +"Flor" +, +"Flora" +, +"Florance" +, +"Flore" +, +"Florella" +, +"Florence" +, +"Florencia" +, +"Florentia" +, +"Florenza" +, +"Florette" +, +"Flori" +, +"Floria" +, +"Florida" +, +"Florie" +, +"Florina" +, +"Florinda" +, +"Floris" +, +"Florri" +, +"Florrie" +, +"Florry" +, +"Flory" +, +"Flossi" +, +"Flossie" +, +"Flossy" +, +"Flss" +, +"Fran" +, +"Francene" +, +"Frances" +, +"Francesca" +, +"Francine" +, +"Francisca" +, +"Franciska" +, +"Francoise" +, +"Francyne" +, +"Frank" +, +"Frankie" +, +"Franky" +, +"Franni" +, +"Frannie" +, +"Franny" +, +"Frayda" +, +"Fred" +, +"Freda" +, +"Freddi" +, +"Freddie" +, +"Freddy" +, +"Fredelia" +, +"Frederica" +, +"Fredericka" +, +"Frederique" +, +"Fredi" +, +"Fredia" +, +"Fredra" +, +"Fredrika" +, +"Freida" +, +"Frieda" +, +"Friederike" +, +"Fulvia" +, +"Gabbey" +, +"Gabbi" +, +"Gabbie" +, +"Gabey" +, +"Gabi" +, +"Gabie" +, +"Gabriel" +, +"Gabriela" +, +"Gabriell" +, +"Gabriella" +, +"Gabrielle" +, +"Gabriellia" +, +"Gabrila" +, +"Gaby" +, +"Gae" +, +"Gael" +, +"Gail" +, +"Gale" +, +"Gale" +, +"Galina" +, +"Garland" +, +"Garnet" +, +"Garnette" +, +"Gates" +, +"Gavra" +, +"Gavrielle" +, +"Gay" +, +"Gaye" +, +"Gayel" +, +"Gayla" +, +"Gayle" +, +"Gayleen" +, +"Gaylene" +, +"Gaynor" +, +"Gelya" +, +"Gena" +, +"Gene" +, +"Geneva" +, +"Genevieve" +, +"Genevra" +, +"Genia" +, +"Genna" +, +"Genni" +, +"Gennie" +, +"Gennifer" +, +"Genny" +, +"Genovera" +, +"Genvieve" +, +"George" +, +"Georgeanna" +, +"Georgeanne" +, +"Georgena" +, +"Georgeta" +, +"Georgetta" +, +"Georgette" +, +"Georgia" +, +"Georgiana" +, +"Georgianna" +, +"Georgianne" +, +"Georgie" +, +"Georgina" +, +"Georgine" +, +"Geralda" +, +"Geraldine" +, +"Gerda" +, +"Gerhardine" +, +"Geri" +, +"Gerianna" +, +"Gerianne" +, +"Gerladina" +, +"Germain" +, +"Germaine" +, +"Germana" +, +"Gerri" +, +"Gerrie" +, +"Gerrilee" +, +"Gerry" +, +"Gert" +, +"Gerta" +, +"Gerti" +, +"Gertie" +, +"Gertrud" +, +"Gertruda" +, +"Gertrude" +, +"Gertrudis" +, +"Gerty" +, +"Giacinta" +, +"Giana" +, +"Gianina" +, +"Gianna" +, +"Gigi" +, +"Gilberta" +, +"Gilberte" +, +"Gilbertina" +, +"Gilbertine" +, +"Gilda" +, +"Gilemette" +, +"Gill" +, +"Gillan" +, +"Gilli" +, +"Gillian" +, +"Gillie" +, +"Gilligan" +, +"Gilly" +, +"Gina" +, +"Ginelle" +, +"Ginevra" +, +"Ginger" +, +"Ginni" +, +"Ginnie" +, +"Ginnifer" +, +"Ginny" +, +"Giorgia" +, +"Giovanna" +, +"Gipsy" +, +"Giralda" +, +"Gisela" +, +"Gisele" +, +"Gisella" +, +"Giselle" +, +"Giuditta" +, +"Giulia" +, +"Giulietta" +, +"Giustina" +, +"Gizela" +, +"Glad" +, +"Gladi" +, +"Gladys" +, +"Gleda" +, +"Glen" +, +"Glenda" +, +"Glenine" +, +"Glenn" +, +"Glenna" +, +"Glennie" +, +"Glennis" +, +"Glori" +, +"Gloria" +, +"Gloriana" +, +"Gloriane" +, +"Glory" +, +"Glyn" +, +"Glynda" +, +"Glynis" +, +"Glynnis" +, +"Gnni" +, +"Godiva" +, +"Golda" +, +"Goldarina" +, +"Goldi" +, +"Goldia" +, +"Goldie" +, +"Goldina" +, +"Goldy" +, +"Grace" +, +"Gracia" +, +"Gracie" +, +"Grata" +, +"Gratia" +, +"Gratiana" +, +"Gray" +, +"Grayce" +, +"Grazia" +, +"Greer" +, +"Greta" +, +"Gretal" +, +"Gretchen" +, +"Grete" +, +"Gretel" +, +"Grethel" +, +"Gretna" +, +"Gretta" +, +"Grier" +, +"Griselda" +, +"Grissel" +, +"Guendolen" +, +"Guenevere" +, +"Guenna" +, +"Guglielma" +, +"Gui" +, +"Guillema" +, +"Guillemette" +, +"Guinevere" +, +"Guinna" +, +"Gunilla" +, +"Gus" +, +"Gusella" +, +"Gussi" +, +"Gussie" +, +"Gussy" +, +"Gusta" +, +"Gusti" +, +"Gustie" +, +"Gusty" +, +"Gwen" +, +"Gwendolen" +, +"Gwendolin" +, +"Gwendolyn" +, +"Gweneth" +, +"Gwenette" +, +"Gwenneth" +, +"Gwenni" +, +"Gwennie" +, +"Gwenny" +, +"Gwenora" +, +"Gwenore" +, +"Gwyn" +, +"Gwyneth" +, +"Gwynne" +, +"Gypsy" +, +"Hadria" +, +"Hailee" +, +"Haily" +, +"Haleigh" +, +"Halette" +, +"Haley" +, +"Hali" +, +"Halie" +, +"Halimeda" +, +"Halley" +, +"Halli" +, +"Hallie" +, +"Hally" +, +"Hana" +, +"Hanna" +, +"Hannah" +, +"Hanni" +, +"Hannie" +, +"Hannis" +, +"Hanny" +, +"Happy" +, +"Harlene" +, +"Harley" +, +"Harli" +, +"Harlie" +, +"Harmonia" +, +"Harmonie" +, +"Harmony" +, +"Harri" +, +"Harrie" +, +"Harriet" +, +"Harriett" +, +"Harrietta" +, +"Harriette" +, +"Harriot" +, +"Harriott" +, +"Hatti" +, +"Hattie" +, +"Hatty" +, +"Hayley" +, +"Hazel" +, +"Heath" +, +"Heather" +, +"Heda" +, +"Hedda" +, +"Heddi" +, +"Heddie" +, +"Hedi" +, +"Hedvig" +, +"Hedvige" +, +"Hedwig" +, +"Hedwiga" +, +"Hedy" +, +"Heida" +, +"Heidi" +, +"Heidie" +, +"Helaina" +, +"Helaine" +, +"Helen" +, +"Helen-Elizabeth" +, +"Helena" +, +"Helene" +, +"Helenka" +, +"Helga" +, +"Helge" +, +"Helli" +, +"Heloise" +, +"Helsa" +, +"Helyn" +, +"Hendrika" +, +"Henka" +, +"Henrie" +, +"Henrieta" +, +"Henrietta" +, +"Henriette" +, +"Henryetta" +, +"Hephzibah" +, +"Hermia" +, +"Hermina" +, +"Hermine" +, +"Herminia" +, +"Hermione" +, +"Herta" +, +"Hertha" +, +"Hester" +, +"Hesther" +, +"Hestia" +, +"Hetti" +, +"Hettie" +, +"Hetty" +, +"Hilary" +, +"Hilda" +, +"Hildagard" +, +"Hildagarde" +, +"Hilde" +, +"Hildegaard" +, +"Hildegarde" +, +"Hildy" +, +"Hillary" +, +"Hilliary" +, +"Hinda" +, +"Holli" +, +"Hollie" +, +"Holly" +, +"Holly-Anne" +, +"Hollyanne" +, +"Honey" +, +"Honor" +, +"Honoria" +, +"Hope" +, +"Horatia" +, +"Hortense" +, +"Hortensia" +, +"Hulda" +, +"Hyacinth" +, +"Hyacintha" +, +"Hyacinthe" +, +"Hyacinthia" +, +"Hyacinthie" +, +"Hynda" +, +"Ianthe" +, +"Ibbie" +, +"Ibby" +, +"Ida" +, +"Idalia" +, +"Idalina" +, +"Idaline" +, +"Idell" +, +"Idelle" +, +"Idette" +, +"Ileana" +, +"Ileane" +, +"Ilene" +, +"Ilise" +, +"Ilka" +, +"Illa" +, +"Ilsa" +, +"Ilse" +, +"Ilysa" +, +"Ilyse" +, +"Ilyssa" +, +"Imelda" +, +"Imogen" +, +"Imogene" +, +"Imojean" +, +"Ina" +, +"Indira" +, +"Ines" +, +"Inesita" +, +"Inessa" +, +"Inez" +, +"Inga" +, +"Ingaberg" +, +"Ingaborg" +, +"Inge" +, +"Ingeberg" +, +"Ingeborg" +, +"Inger" +, +"Ingrid" +, +"Ingunna" +, +"Inna" +, +"Iolande" +, +"Iolanthe" +, +"Iona" +, +"Iormina" +, +"Ira" +, +"Irena" +, +"Irene" +, +"Irina" +, +"Iris" +, +"Irita" +, +"Irma" +, +"Isa" +, +"Isabel" +, +"Isabelita" +, +"Isabella" +, +"Isabelle" +, +"Isadora" +, +"Isahella" +, +"Iseabal" +, +"Isidora" +, +"Isis" +, +"Isobel" +, +"Issi" +, +"Issie" +, +"Issy" +, +"Ivett" +, +"Ivette" +, +"Ivie" +, +"Ivonne" +, +"Ivory" +, +"Ivy" +, +"Izabel" +, +"Jacenta" +, +"Jacinda" +, +"Jacinta" +, +"Jacintha" +, +"Jacinthe" +, +"Jackelyn" +, +"Jacki" +, +"Jackie" +, +"Jacklin" +, +"Jacklyn" +, +"Jackquelin" +, +"Jackqueline" +, +"Jacky" +, +"Jaclin" +, +"Jaclyn" +, +"Jacquelin" +, +"Jacqueline" +, +"Jacquelyn" +, +"Jacquelynn" +, +"Jacquenetta" +, +"Jacquenette" +, +"Jacquetta" +, +"Jacquette" +, +"Jacqui" +, +"Jacquie" +, +"Jacynth" +, +"Jada" +, +"Jade" +, +"Jaime" +, +"Jaimie" +, +"Jaine" +, +"Jami" +, +"Jamie" +, +"Jamima" +, +"Jammie" +, +"Jan" +, +"Jana" +, +"Janaya" +, +"Janaye" +, +"Jandy" +, +"Jane" +, +"Janean" +, +"Janeczka" +, +"Janeen" +, +"Janel" +, +"Janela" +, +"Janella" +, +"Janelle" +, +"Janene" +, +"Janenna" +, +"Janessa" +, +"Janet" +, +"Janeta" +, +"Janetta" +, +"Janette" +, +"Janeva" +, +"Janey" +, +"Jania" +, +"Janice" +, +"Janie" +, +"Janifer" +, +"Janina" +, +"Janine" +, +"Janis" +, +"Janith" +, +"Janka" +, +"Janna" +, +"Jannel" +, +"Jannelle" +, +"Janot" +, +"Jany" +, +"Jaquelin" +, +"Jaquelyn" +, +"Jaquenetta" +, +"Jaquenette" +, +"Jaquith" +, +"Jasmin" +, +"Jasmina" +, +"Jasmine" +, +"Jayme" +, +"Jaymee" +, +"Jayne" +, +"Jaynell" +, +"Jazmin" +, +"Jean" +, +"Jeana" +, +"Jeane" +, +"Jeanelle" +, +"Jeanette" +, +"Jeanie" +, +"Jeanine" +, +"Jeanna" +, +"Jeanne" +, +"Jeannette" +, +"Jeannie" +, +"Jeannine" +, +"Jehanna" +, +"Jelene" +, +"Jemie" +, +"Jemima" +, +"Jemimah" +, +"Jemmie" +, +"Jemmy" +, +"Jen" +, +"Jena" +, +"Jenda" +, +"Jenelle" +, +"Jeni" +, +"Jenica" +, +"Jeniece" +, +"Jenifer" +, +"Jeniffer" +, +"Jenilee" +, +"Jenine" +, +"Jenn" +, +"Jenna" +, +"Jennee" +, +"Jennette" +, +"Jenni" +, +"Jennica" +, +"Jennie" +, +"Jennifer" +, +"Jennilee" +, +"Jennine" +, +"Jenny" +, +"Jeralee" +, +"Jere" +, +"Jeri" +, +"Jermaine" +, +"Jerrie" +, +"Jerrilee" +, +"Jerrilyn" +, +"Jerrine" +, +"Jerry" +, +"Jerrylee" +, +"Jess" +, +"Jessa" +, +"Jessalin" +, +"Jessalyn" +, +"Jessamine" +, +"Jessamyn" +, +"Jesse" +, +"Jesselyn" +, +"Jessi" +, +"Jessica" +, +"Jessie" +, +"Jessika" +, +"Jessy" +, +"Jewel" +, +"Jewell" +, +"Jewelle" +, +"Jill" +, +"Jillana" +, +"Jillane" +, +"Jillayne" +, +"Jilleen" +, +"Jillene" +, +"Jilli" +, +"Jillian" +, +"Jillie" +, +"Jilly" +, +"Jinny" +, +"Jo" +, +"Jo Ann" +, +"Jo-Ann" +, +"Jo-Anne" +, +"Joan" +, +"Joana" +, +"Joane" +, +"Joanie" +, +"Joann" +, +"Joanna" +, +"Joanne" +, +"Joannes" +, +"Jobey" +, +"Jobi" +, +"Jobie" +, +"Jobina" +, +"Joby" +, +"Jobye" +, +"Jobyna" +, +"Jocelin" +, +"Joceline" +, +"Jocelyn" +, +"Jocelyne" +, +"Jodee" +, +"Jodi" +, +"Jodie" +, +"Jody" +, +"Joeann" +, +"Joela" +, +"Joelie" +, +"Joell" +, +"Joella" +, +"Joelle" +, +"Joellen" +, +"Joelly" +, +"Joellyn" +, +"Joelynn" +, +"Joete" +, +"Joey" +, +"Johanna" +, +"Johannah" +, +"Johna" +, +"Johnath" +, +"Johnette" +, +"Johnna" +, +"Joice" +, +"Jojo" +, +"Jolee" +, +"Joleen" +, +"Jolene" +, +"Joletta" +, +"Joli" +, +"Jolie" +, +"Joline" +, +"Joly" +, +"Jolyn" +, +"Jolynn" +, +"Jonell" +, +"Joni" +, +"Jonie" +, +"Jonis" +, +"Jordain" +, +"Jordan" +, +"Jordana" +, +"Jordanna" +, +"Jorey" +, +"Jori" +, +"Jorie" +, +"Jorrie" +, +"Jorry" +, +"Joscelin" +, +"Josee" +, +"Josefa" +, +"Josefina" +, +"Josepha" +, +"Josephina" +, +"Josephine" +, +"Josey" +, +"Josi" +, +"Josie" +, +"Josselyn" +, +"Josy" +, +"Jourdan" +, +"Joy" +, +"Joya" +, +"Joyan" +, +"Joyann" +, +"Joyce" +, +"Joycelin" +, +"Joye" +, +"Jsandye" +, +"Juana" +, +"Juanita" +, +"Judi" +, +"Judie" +, +"Judith" +, +"Juditha" +, +"Judy" +, +"Judye" +, +"Juieta" +, +"Julee" +, +"Juli" +, +"Julia" +, +"Juliana" +, +"Juliane" +, +"Juliann" +, +"Julianna" +, +"Julianne" +, +"Julie" +, +"Julienne" +, +"Juliet" +, +"Julieta" +, +"Julietta" +, +"Juliette" +, +"Julina" +, +"Juline" +, +"Julissa" +, +"Julita" +, +"June" +, +"Junette" +, +"Junia" +, +"Junie" +, +"Junina" +, +"Justina" +, +"Justine" +, +"Justinn" +, +"Jyoti" +, +"Kacey" +, +"Kacie" +, +"Kacy" +, +"Kaela" +, +"Kai" +, +"Kaia" +, +"Kaila" +, +"Kaile" +, +"Kailey" +, +"Kaitlin" +, +"Kaitlyn" +, +"Kaitlynn" +, +"Kaja" +, +"Kakalina" +, +"Kala" +, +"Kaleena" +, +"Kali" +, +"Kalie" +, +"Kalila" +, +"Kalina" +, +"Kalinda" +, +"Kalindi" +, +"Kalli" +, +"Kally" +, +"Kameko" +, +"Kamila" +, +"Kamilah" +, +"Kamillah" +, +"Kandace" +, +"Kandy" +, +"Kania" +, +"Kanya" +, +"Kara" +, +"Kara-Lynn" +, +"Karalee" +, +"Karalynn" +, +"Kare" +, +"Karee" +, +"Karel" +, +"Karen" +, +"Karena" +, +"Kari" +, +"Karia" +, +"Karie" +, +"Karil" +, +"Karilynn" +, +"Karin" +, +"Karina" +, +"Karine" +, +"Kariotta" +, +"Karisa" +, +"Karissa" +, +"Karita" +, +"Karla" +, +"Karlee" +, +"Karleen" +, +"Karlen" +, +"Karlene" +, +"Karlie" +, +"Karlotta" +, +"Karlotte" +, +"Karly" +, +"Karlyn" +, +"Karmen" +, +"Karna" +, +"Karol" +, +"Karola" +, +"Karole" +, +"Karolina" +, +"Karoline" +, +"Karoly" +, +"Karon" +, +"Karrah" +, +"Karrie" +, +"Karry" +, +"Kary" +, +"Karyl" +, +"Karylin" +, +"Karyn" +, +"Kasey" +, +"Kass" +, +"Kassandra" +, +"Kassey" +, +"Kassi" +, +"Kassia" +, +"Kassie" +, +"Kat" +, +"Kata" +, +"Katalin" +, +"Kate" +, +"Katee" +, +"Katerina" +, +"Katerine" +, +"Katey" +, +"Kath" +, +"Katha" +, +"Katharina" +, +"Katharine" +, +"Katharyn" +, +"Kathe" +, +"Katherina" +, +"Katherine" +, +"Katheryn" +, +"Kathi" +, +"Kathie" +, +"Kathleen" +, +"Kathlin" +, +"Kathrine" +, +"Kathryn" +, +"Kathryne" +, +"Kathy" +, +"Kathye" +, +"Kati" +, +"Katie" +, +"Katina" +, +"Katine" +, +"Katinka" +, +"Katleen" +, +"Katlin" +, +"Katrina" +, +"Katrine" +, +"Katrinka" +, +"Katti" +, +"Kattie" +, +"Katuscha" +, +"Katusha" +, +"Katy" +, +"Katya" +, +"Kay" +, +"Kaycee" +, +"Kaye" +, +"Kayla" +, +"Kayle" +, +"Kaylee" +, +"Kayley" +, +"Kaylil" +, +"Kaylyn" +, +"Keeley" +, +"Keelia" +, +"Keely" +, +"Kelcey" +, +"Kelci" +, +"Kelcie" +, +"Kelcy" +, +"Kelila" +, +"Kellen" +, +"Kelley" +, +"Kelli" +, +"Kellia" +, +"Kellie" +, +"Kellina" +, +"Kellsie" +, +"Kelly" +, +"Kellyann" +, +"Kelsey" +, +"Kelsi" +, +"Kelsy" +, +"Kendra" +, +"Kendre" +, +"Kenna" +, +"Keri" +, +"Keriann" +, +"Kerianne" +, +"Kerri" +, +"Kerrie" +, +"Kerrill" +, +"Kerrin" +, +"Kerry" +, +"Kerstin" +, +"Kesley" +, +"Keslie" +, +"Kessia" +, +"Kessiah" +, +"Ketti" +, +"Kettie" +, +"Ketty" +, +"Kevina" +, +"Kevyn" +, +"Ki" +, +"Kiah" +, +"Kial" +, +"Kiele" +, +"Kiersten" +, +"Kikelia" +, +"Kiley" +, +"Kim" +, +"Kimberlee" +, +"Kimberley" +, +"Kimberli" +, +"Kimberly" +, +"Kimberlyn" +, +"Kimbra" +, +"Kimmi" +, +"Kimmie" +, +"Kimmy" +, +"Kinna" +, +"Kip" +, +"Kipp" +, +"Kippie" +, +"Kippy" +, +"Kira" +, +"Kirbee" +, +"Kirbie" +, +"Kirby" +, +"Kiri" +, +"Kirsten" +, +"Kirsteni" +, +"Kirsti" +, +"Kirstin" +, +"Kirstyn" +, +"Kissee" +, +"Kissiah" +, +"Kissie" +, +"Kit" +, +"Kitti" +, +"Kittie" +, +"Kitty" +, +"Kizzee" +, +"Kizzie" +, +"Klara" +, +"Klarika" +, +"Klarrisa" +, +"Konstance" +, +"Konstanze" +, +"Koo" +, +"Kora" +, +"Koral" +, +"Koralle" +, +"Kordula" +, +"Kore" +, +"Korella" +, +"Koren" +, +"Koressa" +, +"Kori" +, +"Korie" +, +"Korney" +, +"Korrie" +, +"Korry" +, +"Kris" +, +"Krissie" +, +"Krissy" +, +"Krista" +, +"Kristal" +, +"Kristan" +, +"Kriste" +, +"Kristel" +, +"Kristen" +, +"Kristi" +, +"Kristien" +, +"Kristin" +, +"Kristina" +, +"Kristine" +, +"Kristy" +, +"Kristyn" +, +"Krysta" +, +"Krystal" +, +"Krystalle" +, +"Krystle" +, +"Krystyna" +, +"Kyla" +, +"Kyle" +, +"Kylen" +, +"Kylie" +, +"Kylila" +, +"Kylynn" +, +"Kym" +, +"Kynthia" +, +"Kyrstin" +, +"La Verne" +, +"Lacee" +, +"Lacey" +, +"Lacie" +, +"Lacy" +, +"Ladonna" +, +"Laetitia" +, +"Laina" +, +"Lainey" +, +"Lana" +, +"Lanae" +, +"Lane" +, +"Lanette" +, +"Laney" +, +"Lani" +, +"Lanie" +, +"Lanita" +, +"Lanna" +, +"Lanni" +, +"Lanny" +, +"Lara" +, +"Laraine" +, +"Lari" +, +"Larina" +, +"Larine" +, +"Larisa" +, +"Larissa" +, +"Lark" +, +"Laryssa" +, +"Latashia" +, +"Latia" +, +"Latisha" +, +"Latrena" +, +"Latrina" +, +"Laura" +, +"Lauraine" +, +"Laural" +, +"Lauralee" +, +"Laure" +, +"Lauree" +, +"Laureen" +, +"Laurel" +, +"Laurella" +, +"Lauren" +, +"Laurena" +, +"Laurene" +, +"Lauretta" +, +"Laurette" +, +"Lauri" +, +"Laurianne" +, +"Laurice" +, +"Laurie" +, +"Lauryn" +, +"Lavena" +, +"Laverna" +, +"Laverne" +, +"Lavina" +, +"Lavinia" +, +"Lavinie" +, +"Layla" +, +"Layne" +, +"Layney" +, +"Lea" +, +"Leah" +, +"Leandra" +, +"Leann" +, +"Leanna" +, +"Leanor" +, +"Leanora" +, +"Lebbie" +, +"Leda" +, +"Lee" +, +"Leeann" +, +"Leeanne" +, +"Leela" +, +"Leelah" +, +"Leena" +, +"Leesa" +, +"Leese" +, +"Legra" +, +"Leia" +, +"Leigh" +, +"Leigha" +, +"Leila" +, +"Leilah" +, +"Leisha" +, +"Lela" +, +"Lelah" +, +"Leland" +, +"Lelia" +, +"Lena" +, +"Lenee" +, +"Lenette" +, +"Lenka" +, +"Lenna" +, +"Lenora" +, +"Lenore" +, +"Leodora" +, +"Leoine" +, +"Leola" +, +"Leoline" +, +"Leona" +, +"Leonanie" +, +"Leone" +, +"Leonelle" +, +"Leonie" +, +"Leonora" +, +"Leonore" +, +"Leontine" +, +"Leontyne" +, +"Leora" +, +"Leshia" +, +"Lesley" +, +"Lesli" +, +"Leslie" +, +"Lesly" +, +"Lesya" +, +"Leta" +, +"Lethia" +, +"Leticia" +, +"Letisha" +, +"Letitia" +, +"Letizia" +, +"Letta" +, +"Letti" +, +"Lettie" +, +"Letty" +, +"Lexi" +, +"Lexie" +, +"Lexine" +, +"Lexis" +, +"Lexy" +, +"Leyla" +, +"Lezlie" +, +"Lia" +, +"Lian" +, +"Liana" +, +"Liane" +, +"Lianna" +, +"Lianne" +, +"Lib" +, +"Libbey" +, +"Libbi" +, +"Libbie" +, +"Libby" +, +"Licha" +, +"Lida" +, +"Lidia" +, +"Liesa" +, +"Lil" +, +"Lila" +, +"Lilah" +, +"Lilas" +, +"Lilia" +, +"Lilian" +, +"Liliane" +, +"Lilias" +, +"Lilith" +, +"Lilla" +, +"Lilli" +, +"Lillian" +, +"Lillis" +, +"Lilllie" +, +"Lilly" +, +"Lily" +, +"Lilyan" +, +"Lin" +, +"Lina" +, +"Lind" +, +"Linda" +, +"Lindi" +, +"Lindie" +, +"Lindsay" +, +"Lindsey" +, +"Lindsy" +, +"Lindy" +, +"Linea" +, +"Linell" +, +"Linet" +, +"Linette" +, +"Linn" +, +"Linnea" +, +"Linnell" +, +"Linnet" +, +"Linnie" +, +"Linzy" +, +"Lira" +, +"Lisa" +, +"Lisabeth" +, +"Lisbeth" +, +"Lise" +, +"Lisetta" +, +"Lisette" +, +"Lisha" +, +"Lishe" +, +"Lissa" +, +"Lissi" +, +"Lissie" +, +"Lissy" +, +"Lita" +, +"Liuka" +, +"Liv" +, +"Liva" +, +"Livia" +, +"Livvie" +, +"Livvy" +, +"Livvyy" +, +"Livy" +, +"Liz" +, +"Liza" +, +"Lizabeth" +, +"Lizbeth" +, +"Lizette" +, +"Lizzie" +, +"Lizzy" +, +"Loella" +, +"Lois" +, +"Loise" +, +"Lola" +, +"Loleta" +, +"Lolita" +, +"Lolly" +, +"Lona" +, +"Lonee" +, +"Loni" +, +"Lonna" +, +"Lonni" +, +"Lonnie" +, +"Lora" +, +"Lorain" +, +"Loraine" +, +"Loralee" +, +"Loralie" +, +"Loralyn" +, +"Loree" +, +"Loreen" +, +"Lorelei" +, +"Lorelle" +, +"Loren" +, +"Lorena" +, +"Lorene" +, +"Lorenza" +, +"Loretta" +, +"Lorette" +, +"Lori" +, +"Loria" +, +"Lorianna" +, +"Lorianne" +, +"Lorie" +, +"Lorilee" +, +"Lorilyn" +, +"Lorinda" +, +"Lorine" +, +"Lorita" +, +"Lorna" +, +"Lorne" +, +"Lorraine" +, +"Lorrayne" +, +"Lorri" +, +"Lorrie" +, +"Lorrin" +, +"Lorry" +, +"Lory" +, +"Lotta" +, +"Lotte" +, +"Lotti" +, +"Lottie" +, +"Lotty" +, +"Lou" +, +"Louella" +, +"Louisa" +, +"Louise" +, +"Louisette" +, +"Loutitia" +, +"Lu" +, +"Luce" +, +"Luci" +, +"Lucia" +, +"Luciana" +, +"Lucie" +, +"Lucienne" +, +"Lucila" +, +"Lucilia" +, +"Lucille" +, +"Lucina" +, +"Lucinda" +, +"Lucine" +, +"Lucita" +, +"Lucky" +, +"Lucretia" +, +"Lucy" +, +"Ludovika" +, +"Luella" +, +"Luelle" +, +"Luisa" +, +"Luise" +, +"Lula" +, +"Lulita" +, +"Lulu" +, +"Lura" +, +"Lurette" +, +"Lurleen" +, +"Lurlene" +, +"Lurline" +, +"Lusa" +, +"Luz" +, +"Lyda" +, +"Lydia" +, +"Lydie" +, +"Lyn" +, +"Lynda" +, +"Lynde" +, +"Lyndel" +, +"Lyndell" +, +"Lyndsay" +, +"Lyndsey" +, +"Lyndsie" +, +"Lyndy" +, +"Lynea" +, +"Lynelle" +, +"Lynett" +, +"Lynette" +, +"Lynn" +, +"Lynna" +, +"Lynne" +, +"Lynnea" +, +"Lynnell" +, +"Lynnelle" +, +"Lynnet" +, +"Lynnett" +, +"Lynnette" +, +"Lynsey" +, +"Lyssa" +, +"Mab" +, +"Mabel" +, +"Mabelle" +, +"Mable" +, +"Mada" +, +"Madalena" +, +"Madalyn" +, +"Maddalena" +, +"Maddi" +, +"Maddie" +, +"Maddy" +, +"Madel" +, +"Madelaine" +, +"Madeleine" +, +"Madelena" +, +"Madelene" +, +"Madelin" +, +"Madelina" +, +"Madeline" +, +"Madella" +, +"Madelle" +, +"Madelon" +, +"Madelyn" +, +"Madge" +, +"Madlen" +, +"Madlin" +, +"Madonna" +, +"Mady" +, +"Mae" +, +"Maegan" +, +"Mag" +, +"Magda" +, +"Magdaia" +, +"Magdalen" +, +"Magdalena" +, +"Magdalene" +, +"Maggee" +, +"Maggi" +, +"Maggie" +, +"Maggy" +, +"Mahala" +, +"Mahalia" +, +"Maia" +, +"Maible" +, +"Maiga" +, +"Maighdiln" +, +"Mair" +, +"Maire" +, +"Maisey" +, +"Maisie" +, +"Maitilde" +, +"Mala" +, +"Malanie" +, +"Malena" +, +"Malia" +, +"Malina" +, +"Malinda" +, +"Malinde" +, +"Malissa" +, +"Malissia" +, +"Mallissa" +, +"Mallorie" +, +"Mallory" +, +"Malorie" +, +"Malory" +, +"Malva" +, +"Malvina" +, +"Malynda" +, +"Mame" +, +"Mamie" +, +"Manda" +, +"Mandi" +, +"Mandie" +, +"Mandy" +, +"Manon" +, +"Manya" +, +"Mara" +, +"Marabel" +, +"Marcela" +, +"Marcelia" +, +"Marcella" +, +"Marcelle" +, +"Marcellina" +, +"Marcelline" +, +"Marchelle" +, +"Marci" +, +"Marcia" +, +"Marcie" +, +"Marcile" +, +"Marcille" +, +"Marcy" +, +"Mareah" +, +"Maren" +, +"Marena" +, +"Maressa" +, +"Marga" +, +"Margalit" +, +"Margalo" +, +"Margaret" +, +"Margareta" +, +"Margarete" +, +"Margaretha" +, +"Margarethe" +, +"Margaretta" +, +"Margarette" +, +"Margarita" +, +"Margaux" +, +"Marge" +, +"Margeaux" +, +"Margery" +, +"Marget" +, +"Margette" +, +"Margi" +, +"Margie" +, +"Margit" +, +"Margo" +, +"Margot" +, +"Margret" +, +"Marguerite" +, +"Margy" +, +"Mari" +, +"Maria" +, +"Mariam" +, +"Marian" +, +"Mariana" +, +"Mariann" +, +"Marianna" +, +"Marianne" +, +"Maribel" +, +"Maribelle" +, +"Maribeth" +, +"Marice" +, +"Maridel" +, +"Marie" +, +"Marie-Ann" +, +"Marie-Jeanne" +, +"Marieann" +, +"Mariejeanne" +, +"Mariel" +, +"Mariele" +, +"Marielle" +, +"Mariellen" +, +"Marietta" +, +"Mariette" +, +"Marigold" +, +"Marijo" +, +"Marika" +, +"Marilee" +, +"Marilin" +, +"Marillin" +, +"Marilyn" +, +"Marin" +, +"Marina" +, +"Marinna" +, +"Marion" +, +"Mariquilla" +, +"Maris" +, +"Marisa" +, +"Mariska" +, +"Marissa" +, +"Marita" +, +"Maritsa" +, +"Mariya" +, +"Marj" +, +"Marja" +, +"Marje" +, +"Marji" +, +"Marjie" +, +"Marjorie" +, +"Marjory" +, +"Marjy" +, +"Marketa" +, +"Marla" +, +"Marlane" +, +"Marleah" +, +"Marlee" +, +"Marleen" +, +"Marlena" +, +"Marlene" +, +"Marley" +, +"Marlie" +, +"Marline" +, +"Marlo" +, +"Marlyn" +, +"Marna" +, +"Marne" +, +"Marney" +, +"Marni" +, +"Marnia" +, +"Marnie" +, +"Marquita" +, +"Marrilee" +, +"Marris" +, +"Marrissa" +, +"Marsha" +, +"Marsiella" +, +"Marta" +, +"Martelle" +, +"Martguerita" +, +"Martha" +, +"Marthe" +, +"Marthena" +, +"Marti" +, +"Martica" +, +"Martie" +, +"Martina" +, +"Martita" +, +"Marty" +, +"Martynne" +, +"Mary" +, +"Marya" +, +"Maryann" +, +"Maryanna" +, +"Maryanne" +, +"Marybelle" +, +"Marybeth" +, +"Maryellen" +, +"Maryjane" +, +"Maryjo" +, +"Maryl" +, +"Marylee" +, +"Marylin" +, +"Marylinda" +, +"Marylou" +, +"Marylynne" +, +"Maryrose" +, +"Marys" +, +"Marysa" +, +"Masha" +, +"Matelda" +, +"Mathilda" +, +"Mathilde" +, +"Matilda" +, +"Matilde" +, +"Matti" +, +"Mattie" +, +"Matty" +, +"Maud" +, +"Maude" +, +"Maudie" +, +"Maura" +, +"Maure" +, +"Maureen" +, +"Maureene" +, +"Maurene" +, +"Maurine" +, +"Maurise" +, +"Maurita" +, +"Maurizia" +, +"Mavis" +, +"Mavra" +, +"Max" +, +"Maxi" +, +"Maxie" +, +"Maxine" +, +"Maxy" +, +"May" +, +"Maybelle" +, +"Maye" +, +"Mead" +, +"Meade" +, +"Meagan" +, +"Meaghan" +, +"Meara" +, +"Mechelle" +, +"Meg" +, +"Megan" +, +"Megen" +, +"Meggi" +, +"Meggie" +, +"Meggy" +, +"Meghan" +, +"Meghann" +, +"Mehetabel" +, +"Mei" +, +"Mel" +, +"Mela" +, +"Melamie" +, +"Melania" +, +"Melanie" +, +"Melantha" +, +"Melany" +, +"Melba" +, +"Melesa" +, +"Melessa" +, +"Melicent" +, +"Melina" +, +"Melinda" +, +"Melinde" +, +"Melisa" +, +"Melisande" +, +"Melisandra" +, +"Melisenda" +, +"Melisent" +, +"Melissa" +, +"Melisse" +, +"Melita" +, +"Melitta" +, +"Mella" +, +"Melli" +, +"Mellicent" +, +"Mellie" +, +"Mellisa" +, +"Mellisent" +, +"Melloney" +, +"Melly" +, +"Melodee" +, +"Melodie" +, +"Melody" +, +"Melonie" +, +"Melony" +, +"Melosa" +, +"Melva" +, +"Mercedes" +, +"Merci" +, +"Mercie" +, +"Mercy" +, +"Meredith" +, +"Meredithe" +, +"Meridel" +, +"Meridith" +, +"Meriel" +, +"Merilee" +, +"Merilyn" +, +"Meris" +, +"Merissa" +, +"Merl" +, +"Merla" +, +"Merle" +, +"Merlina" +, +"Merline" +, +"Merna" +, +"Merola" +, +"Merralee" +, +"Merridie" +, +"Merrie" +, +"Merrielle" +, +"Merrile" +, +"Merrilee" +, +"Merrili" +, +"Merrill" +, +"Merrily" +, +"Merry" +, +"Mersey" +, +"Meryl" +, +"Meta" +, +"Mia" +, +"Micaela" +, +"Michaela" +, +"Michaelina" +, +"Michaeline" +, +"Michaella" +, +"Michal" +, +"Michel" +, +"Michele" +, +"Michelina" +, +"Micheline" +, +"Michell" +, +"Michelle" +, +"Micki" +, +"Mickie" +, +"Micky" +, +"Midge" +, +"Mignon" +, +"Mignonne" +, +"Miguela" +, +"Miguelita" +, +"Mikaela" +, +"Mil" +, +"Mildred" +, +"Mildrid" +, +"Milena" +, +"Milicent" +, +"Milissent" +, +"Milka" +, +"Milli" +, +"Millicent" +, +"Millie" +, +"Millisent" +, +"Milly" +, +"Milzie" +, +"Mimi" +, +"Min" +, +"Mina" +, +"Minda" +, +"Mindy" +, +"Minerva" +, +"Minetta" +, +"Minette" +, +"Minna" +, +"Minnaminnie" +, +"Minne" +, +"Minni" +, +"Minnie" +, +"Minnnie" +, +"Minny" +, +"Minta" +, +"Miof Mela" +, +"Miquela" +, +"Mira" +, +"Mirabel" +, +"Mirabella" +, +"Mirabelle" +, +"Miran" +, +"Miranda" +, +"Mireielle" +, +"Mireille" +, +"Mirella" +, +"Mirelle" +, +"Miriam" +, +"Mirilla" +, +"Mirna" +, +"Misha" +, +"Missie" +, +"Missy" +, +"Misti" +, +"Misty" +, +"Mitzi" +, +"Modesta" +, +"Modestia" +, +"Modestine" +, +"Modesty" +, +"Moina" +, +"Moira" +, +"Moll" +, +"Mollee" +, +"Molli" +, +"Mollie" +, +"Molly" +, +"Mommy" +, +"Mona" +, +"Monah" +, +"Monica" +, +"Monika" +, +"Monique" +, +"Mora" +, +"Moreen" +, +"Morena" +, +"Morgan" +, +"Morgana" +, +"Morganica" +, +"Morganne" +, +"Morgen" +, +"Moria" +, +"Morissa" +, +"Morna" +, +"Moselle" +, +"Moyna" +, +"Moyra" +, +"Mozelle" +, +"Muffin" +, +"Mufi" +, +"Mufinella" +, +"Muire" +, +"Mureil" +, +"Murial" +, +"Muriel" +, +"Murielle" +, +"Myra" +, +"Myrah" +, +"Myranda" +, +"Myriam" +, +"Myrilla" +, +"Myrle" +, +"Myrlene" +, +"Myrna" +, +"Myrta" +, +"Myrtia" +, +"Myrtice" +, +"Myrtie" +, +"Myrtle" +, +"Nada" +, +"Nadean" +, +"Nadeen" +, +"Nadia" +, +"Nadine" +, +"Nadiya" +, +"Nady" +, +"Nadya" +, +"Nalani" +, +"Nan" +, +"Nana" +, +"Nananne" +, +"Nance" +, +"Nancee" +, +"Nancey" +, +"Nanci" +, +"Nancie" +, +"Nancy" +, +"Nanete" +, +"Nanette" +, +"Nani" +, +"Nanice" +, +"Nanine" +, +"Nannette" +, +"Nanni" +, +"Nannie" +, +"Nanny" +, +"Nanon" +, +"Naoma" +, +"Naomi" +, +"Nara" +, +"Nari" +, +"Nariko" +, +"Nat" +, +"Nata" +, +"Natala" +, +"Natalee" +, +"Natalie" +, +"Natalina" +, +"Nataline" +, +"Natalya" +, +"Natasha" +, +"Natassia" +, +"Nathalia" +, +"Nathalie" +, +"Natividad" +, +"Natka" +, +"Natty" +, +"Neala" +, +"Neda" +, +"Nedda" +, +"Nedi" +, +"Neely" +, +"Neila" +, +"Neile" +, +"Neilla" +, +"Neille" +, +"Nelia" +, +"Nelie" +, +"Nell" +, +"Nelle" +, +"Nelli" +, +"Nellie" +, +"Nelly" +, +"Nerissa" +, +"Nerita" +, +"Nert" +, +"Nerta" +, +"Nerte" +, +"Nerti" +, +"Nertie" +, +"Nerty" +, +"Nessa" +, +"Nessi" +, +"Nessie" +, +"Nessy" +, +"Nesta" +, +"Netta" +, +"Netti" +, +"Nettie" +, +"Nettle" +, +"Netty" +, +"Nevsa" +, +"Neysa" +, +"Nichol" +, +"Nichole" +, +"Nicholle" +, +"Nicki" +, +"Nickie" +, +"Nicky" +, +"Nicol" +, +"Nicola" +, +"Nicole" +, +"Nicolea" +, +"Nicolette" +, +"Nicoli" +, +"Nicolina" +, +"Nicoline" +, +"Nicolle" +, +"Nikaniki" +, +"Nike" +, +"Niki" +, +"Nikki" +, +"Nikkie" +, +"Nikoletta" +, +"Nikolia" +, +"Nina" +, +"Ninetta" +, +"Ninette" +, +"Ninnetta" +, +"Ninnette" +, +"Ninon" +, +"Nissa" +, +"Nisse" +, +"Nissie" +, +"Nissy" +, +"Nita" +, +"Nixie" +, +"Noami" +, +"Noel" +, +"Noelani" +, +"Noell" +, +"Noella" +, +"Noelle" +, +"Noellyn" +, +"Noelyn" +, +"Noemi" +, +"Nola" +, +"Nolana" +, +"Nolie" +, +"Nollie" +, +"Nomi" +, +"Nona" +, +"Nonah" +, +"Noni" +, +"Nonie" +, +"Nonna" +, +"Nonnah" +, +"Nora" +, +"Norah" +, +"Norean" +, +"Noreen" +, +"Norene" +, +"Norina" +, +"Norine" +, +"Norma" +, +"Norri" +, +"Norrie" +, +"Norry" +, +"Novelia" +, +"Nydia" +, +"Nyssa" +, +"Octavia" +, +"Odele" +, +"Odelia" +, +"Odelinda" +, +"Odella" +, +"Odelle" +, +"Odessa" +, +"Odetta" +, +"Odette" +, +"Odilia" +, +"Odille" +, +"Ofelia" +, +"Ofella" +, +"Ofilia" +, +"Ola" +, +"Olenka" +, +"Olga" +, +"Olia" +, +"Olimpia" +, +"Olive" +, +"Olivette" +, +"Olivia" +, +"Olivie" +, +"Oliy" +, +"Ollie" +, +"Olly" +, +"Olva" +, +"Olwen" +, +"Olympe" +, +"Olympia" +, +"Olympie" +, +"Ondrea" +, +"Oneida" +, +"Onida" +, +"Oona" +, +"Opal" +, +"Opalina" +, +"Opaline" +, +"Ophelia" +, +"Ophelie" +, +"Ora" +, +"Oralee" +, +"Oralia" +, +"Oralie" +, +"Oralla" +, +"Oralle" +, +"Orel" +, +"Orelee" +, +"Orelia" +, +"Orelie" +, +"Orella" +, +"Orelle" +, +"Oriana" +, +"Orly" +, +"Orsa" +, +"Orsola" +, +"Ortensia" +, +"Otha" +, +"Othelia" +, +"Othella" +, +"Othilia" +, +"Othilie" +, +"Ottilie" +, +"Page" +, +"Paige" +, +"Paloma" +, +"Pam" +, +"Pamela" +, +"Pamelina" +, +"Pamella" +, +"Pammi" +, +"Pammie" +, +"Pammy" +, +"Pandora" +, +"Pansie" +, +"Pansy" +, +"Paola" +, +"Paolina" +, +"Papagena" +, +"Pat" +, +"Patience" +, +"Patrica" +, +"Patrice" +, +"Patricia" +, +"Patrizia" +, +"Patsy" +, +"Patti" +, +"Pattie" +, +"Patty" +, +"Paula" +, +"Paule" +, +"Pauletta" +, +"Paulette" +, +"Pauli" +, +"Paulie" +, +"Paulina" +, +"Pauline" +, +"Paulita" +, +"Pauly" +, +"Pavia" +, +"Pavla" +, +"Pearl" +, +"Pearla" +, +"Pearle" +, +"Pearline" +, +"Peg" +, +"Pegeen" +, +"Peggi" +, +"Peggie" +, +"Peggy" +, +"Pen" +, +"Penelopa" +, +"Penelope" +, +"Penni" +, +"Pennie" +, +"Penny" +, +"Pepi" +, +"Pepita" +, +"Peri" +, +"Peria" +, +"Perl" +, +"Perla" +, +"Perle" +, +"Perri" +, +"Perrine" +, +"Perry" +, +"Persis" +, +"Pet" +, +"Peta" +, +"Petra" +, +"Petrina" +, +"Petronella" +, +"Petronia" +, +"Petronilla" +, +"Petronille" +, +"Petunia" +, +"Phaedra" +, +"Phaidra" +, +"Phebe" +, +"Phedra" +, +"Phelia" +, +"Phil" +, +"Philipa" +, +"Philippa" +, +"Philippe" +, +"Philippine" +, +"Philis" +, +"Phillida" +, +"Phillie" +, +"Phillis" +, +"Philly" +, +"Philomena" +, +"Phoebe" +, +"Phylis" +, +"Phyllida" +, +"Phyllis" +, +"Phyllys" +, +"Phylys" +, +"Pia" +, +"Pier" +, +"Pierette" +, +"Pierrette" +, +"Pietra" +, +"Piper" +, +"Pippa" +, +"Pippy" +, +"Polly" +, +"Pollyanna" +, +"Pooh" +, +"Poppy" +, +"Portia" +, +"Pris" +, +"Prisca" +, +"Priscella" +, +"Priscilla" +, +"Prissie" +, +"Pru" +, +"Prudence" +, +"Prudi" +, +"Prudy" +, +"Prue" +, +"Queenie" +, +"Quentin" +, +"Querida" +, +"Quinn" +, +"Quinta" +, +"Quintana" +, +"Quintilla" +, +"Quintina" +, +"Rachael" +, +"Rachel" +, +"Rachele" +, +"Rachelle" +, +"Rae" +, +"Raeann" +, +"Raf" +, +"Rafa" +, +"Rafaela" +, +"Rafaelia" +, +"Rafaelita" +, +"Rahal" +, +"Rahel" +, +"Raina" +, +"Raine" +, +"Rakel" +, +"Ralina" +, +"Ramona" +, +"Ramonda" +, +"Rana" +, +"Randa" +, +"Randee" +, +"Randene" +, +"Randi" +, +"Randie" +, +"Randy" +, +"Ranee" +, +"Rani" +, +"Rania" +, +"Ranice" +, +"Ranique" +, +"Ranna" +, +"Raphaela" +, +"Raquel" +, +"Raquela" +, +"Rasia" +, +"Rasla" +, +"Raven" +, +"Ray" +, +"Raychel" +, +"Raye" +, +"Rayna" +, +"Raynell" +, +"Rayshell" +, +"Rea" +, +"Reba" +, +"Rebbecca" +, +"Rebe" +, +"Rebeca" +, +"Rebecca" +, +"Rebecka" +, +"Rebeka" +, +"Rebekah" +, +"Rebekkah" +, +"Ree" +, +"Reeba" +, +"Reena" +, +"Reeta" +, +"Reeva" +, +"Regan" +, +"Reggi" +, +"Reggie" +, +"Regina" +, +"Regine" +, +"Reiko" +, +"Reina" +, +"Reine" +, +"Remy" +, +"Rena" +, +"Renae" +, +"Renata" +, +"Renate" +, +"Rene" +, +"Renee" +, +"Renell" +, +"Renelle" +, +"Renie" +, +"Rennie" +, +"Reta" +, +"Retha" +, +"Revkah" +, +"Rey" +, +"Reyna" +, +"Rhea" +, +"Rheba" +, +"Rheta" +, +"Rhetta" +, +"Rhiamon" +, +"Rhianna" +, +"Rhianon" +, +"Rhoda" +, +"Rhodia" +, +"Rhodie" +, +"Rhody" +, +"Rhona" +, +"Rhonda" +, +"Riane" +, +"Riannon" +, +"Rianon" +, +"Rica" +, +"Ricca" +, +"Rici" +, +"Ricki" +, +"Rickie" +, +"Ricky" +, +"Riki" +, +"Rikki" +, +"Rina" +, +"Risa" +, +"Rita" +, +"Riva" +, +"Rivalee" +, +"Rivi" +, +"Rivkah" +, +"Rivy" +, +"Roana" +, +"Roanna" +, +"Roanne" +, +"Robbi" +, +"Robbie" +, +"Robbin" +, +"Robby" +, +"Robbyn" +, +"Robena" +, +"Robenia" +, +"Roberta" +, +"Robin" +, +"Robina" +, +"Robinet" +, +"Robinett" +, +"Robinetta" +, +"Robinette" +, +"Robinia" +, +"Roby" +, +"Robyn" +, +"Roch" +, +"Rochell" +, +"Rochella" +, +"Rochelle" +, +"Rochette" +, +"Roda" +, +"Rodi" +, +"Rodie" +, +"Rodina" +, +"Rois" +, +"Romola" +, +"Romona" +, +"Romonda" +, +"Romy" +, +"Rona" +, +"Ronalda" +, +"Ronda" +, +"Ronica" +, +"Ronna" +, +"Ronni" +, +"Ronnica" +, +"Ronnie" +, +"Ronny" +, +"Roobbie" +, +"Rora" +, +"Rori" +, +"Rorie" +, +"Rory" +, +"Ros" +, +"Rosa" +, +"Rosabel" +, +"Rosabella" +, +"Rosabelle" +, +"Rosaleen" +, +"Rosalia" +, +"Rosalie" +, +"Rosalind" +, +"Rosalinda" +, +"Rosalinde" +, +"Rosaline" +, +"Rosalyn" +, +"Rosalynd" +, +"Rosamond" +, +"Rosamund" +, +"Rosana" +, +"Rosanna" +, +"Rosanne" +, +"Rose" +, +"Roseann" +, +"Roseanna" +, +"Roseanne" +, +"Roselia" +, +"Roselin" +, +"Roseline" +, +"Rosella" +, +"Roselle" +, +"Rosemaria" +, +"Rosemarie" +, +"Rosemary" +, +"Rosemonde" +, +"Rosene" +, +"Rosetta" +, +"Rosette" +, +"Roshelle" +, +"Rosie" +, +"Rosina" +, +"Rosita" +, +"Roslyn" +, +"Rosmunda" +, +"Rosy" +, +"Row" +, +"Rowe" +, +"Rowena" +, +"Roxana" +, +"Roxane" +, +"Roxanna" +, +"Roxanne" +, +"Roxi" +, +"Roxie" +, +"Roxine" +, +"Roxy" +, +"Roz" +, +"Rozalie" +, +"Rozalin" +, +"Rozamond" +, +"Rozanna" +, +"Rozanne" +, +"Roze" +, +"Rozele" +, +"Rozella" +, +"Rozelle" +, +"Rozina" +, +"Rubetta" +, +"Rubi" +, +"Rubia" +, +"Rubie" +, +"Rubina" +, +"Ruby" +, +"Ruperta" +, +"Ruth" +, +"Ruthann" +, +"Ruthanne" +, +"Ruthe" +, +"Ruthi" +, +"Ruthie" +, +"Ruthy" +, +"Ryann" +, +"Rycca" +, +"Saba" +, +"Sabina" +, +"Sabine" +, +"Sabra" +, +"Sabrina" +, +"Sacha" +, +"Sada" +, +"Sadella" +, +"Sadie" +, +"Sadye" +, +"Saidee" +, +"Sal" +, +"Salaidh" +, +"Sallee" +, +"Salli" +, +"Sallie" +, +"Sally" +, +"Sallyann" +, +"Sallyanne" +, +"Saloma" +, +"Salome" +, +"Salomi" +, +"Sam" +, +"Samantha" +, +"Samara" +, +"Samaria" +, +"Sammy" +, +"Sande" +, +"Sandi" +, +"Sandie" +, +"Sandra" +, +"Sandy" +, +"Sandye" +, +"Sapphira" +, +"Sapphire" +, +"Sara" +, +"Sara-Ann" +, +"Saraann" +, +"Sarah" +, +"Sarajane" +, +"Saree" +, +"Sarena" +, +"Sarene" +, +"Sarette" +, +"Sari" +, +"Sarina" +, +"Sarine" +, +"Sarita" +, +"Sascha" +, +"Sasha" +, +"Sashenka" +, +"Saudra" +, +"Saundra" +, +"Savina" +, +"Sayre" +, +"Scarlet" +, +"Scarlett" +, +"Sean" +, +"Seana" +, +"Seka" +, +"Sela" +, +"Selena" +, +"Selene" +, +"Selestina" +, +"Selia" +, +"Selie" +, +"Selina" +, +"Selinda" +, +"Seline" +, +"Sella" +, +"Selle" +, +"Selma" +, +"Sena" +, +"Sephira" +, +"Serena" +, +"Serene" +, +"Shae" +, +"Shaina" +, +"Shaine" +, +"Shalna" +, +"Shalne" +, +"Shana" +, +"Shanda" +, +"Shandee" +, +"Shandeigh" +, +"Shandie" +, +"Shandra" +, +"Shandy" +, +"Shane" +, +"Shani" +, +"Shanie" +, +"Shanna" +, +"Shannah" +, +"Shannen" +, +"Shannon" +, +"Shanon" +, +"Shanta" +, +"Shantee" +, +"Shara" +, +"Sharai" +, +"Shari" +, +"Sharia" +, +"Sharity" +, +"Sharl" +, +"Sharla" +, +"Sharleen" +, +"Sharlene" +, +"Sharline" +, +"Sharon" +, +"Sharona" +, +"Sharron" +, +"Sharyl" +, +"Shaun" +, +"Shauna" +, +"Shawn" +, +"Shawna" +, +"Shawnee" +, +"Shay" +, +"Shayla" +, +"Shaylah" +, +"Shaylyn" +, +"Shaylynn" +, +"Shayna" +, +"Shayne" +, +"Shea" +, +"Sheba" +, +"Sheela" +, +"Sheelagh" +, +"Sheelah" +, +"Sheena" +, +"Sheeree" +, +"Sheila" +, +"Sheila-Kathryn" +, +"Sheilah" +, +"Shel" +, +"Shela" +, +"Shelagh" +, +"Shelba" +, +"Shelbi" +, +"Shelby" +, +"Shelia" +, +"Shell" +, +"Shelley" +, +"Shelli" +, +"Shellie" +, +"Shelly" +, +"Shena" +, +"Sher" +, +"Sheree" +, +"Sheri" +, +"Sherie" +, +"Sherill" +, +"Sherilyn" +, +"Sherline" +, +"Sherri" +, +"Sherrie" +, +"Sherry" +, +"Sherye" +, +"Sheryl" +, +"Shina" +, +"Shir" +, +"Shirl" +, +"Shirlee" +, +"Shirleen" +, +"Shirlene" +, +"Shirley" +, +"Shirline" +, +"Shoshana" +, +"Shoshanna" +, +"Siana" +, +"Sianna" +, +"Sib" +, +"Sibbie" +, +"Sibby" +, +"Sibeal" +, +"Sibel" +, +"Sibella" +, +"Sibelle" +, +"Sibilla" +, +"Sibley" +, +"Sibyl" +, +"Sibylla" +, +"Sibylle" +, +"Sidoney" +, +"Sidonia" +, +"Sidonnie" +, +"Sigrid" +, +"Sile" +, +"Sileas" +, +"Silva" +, +"Silvana" +, +"Silvia" +, +"Silvie" +, +"Simona" +, +"Simone" +, +"Simonette" +, +"Simonne" +, +"Sindee" +, +"Siobhan" +, +"Sioux" +, +"Siouxie" +, +"Sisely" +, +"Sisile" +, +"Sissie" +, +"Sissy" +, +"Siusan" +, +"Sofia" +, +"Sofie" +, +"Sondra" +, +"Sonia" +, +"Sonja" +, +"Sonni" +, +"Sonnie" +, +"Sonnnie" +, +"Sonny" +, +"Sonya" +, +"Sophey" +, +"Sophi" +, +"Sophia" +, +"Sophie" +, +"Sophronia" +, +"Sorcha" +, +"Sosanna" +, +"Stace" +, +"Stacee" +, +"Stacey" +, +"Staci" +, +"Stacia" +, +"Stacie" +, +"Stacy" +, +"Stafani" +, +"Star" +, +"Starla" +, +"Starlene" +, +"Starlin" +, +"Starr" +, +"Stefa" +, +"Stefania" +, +"Stefanie" +, +"Steffane" +, +"Steffi" +, +"Steffie" +, +"Stella" +, +"Stepha" +, +"Stephana" +, +"Stephani" +, +"Stephanie" +, +"Stephannie" +, +"Stephenie" +, +"Stephi" +, +"Stephie" +, +"Stephine" +, +"Stesha" +, +"Stevana" +, +"Stevena" +, +"Stoddard" +, +"Storm" +, +"Stormi" +, +"Stormie" +, +"Stormy" +, +"Sue" +, +"Suellen" +, +"Sukey" +, +"Suki" +, +"Sula" +, +"Sunny" +, +"Sunshine" +, +"Susan" +, +"Susana" +, +"Susanetta" +, +"Susann" +, +"Susanna" +, +"Susannah" +, +"Susanne" +, +"Susette" +, +"Susi" +, +"Susie" +, +"Susy" +, +"Suzann" +, +"Suzanna" +, +"Suzanne" +, +"Suzette" +, +"Suzi" +, +"Suzie" +, +"Suzy" +, +"Sybil" +, +"Sybila" +, +"Sybilla" +, +"Sybille" +, +"Sybyl" +, +"Sydel" +, +"Sydelle" +, +"Sydney" +, +"Sylvia" +, +"Tabatha" +, +"Tabbatha" +, +"Tabbi" +, +"Tabbie" +, +"Tabbitha" +, +"Tabby" +, +"Tabina" +, +"Tabitha" +, +"Taffy" +, +"Talia" +, +"Tallia" +, +"Tallie" +, +"Tallou" +, +"Tallulah" +, +"Tally" +, +"Talya" +, +"Talyah" +, +"Tamar" +, +"Tamara" +, +"Tamarah" +, +"Tamarra" +, +"Tamera" +, +"Tami" +, +"Tamiko" +, +"Tamma" +, +"Tammara" +, +"Tammi" +, +"Tammie" +, +"Tammy" +, +"Tamqrah" +, +"Tamra" +, +"Tana" +, +"Tandi" +, +"Tandie" +, +"Tandy" +, +"Tanhya" +, +"Tani" +, +"Tania" +, +"Tanitansy" +, +"Tansy" +, +"Tanya" +, +"Tara" +, +"Tarah" +, +"Tarra" +, +"Tarrah" +, +"Taryn" +, +"Tasha" +, +"Tasia" +, +"Tate" +, +"Tatiana" +, +"Tatiania" +, +"Tatum" +, +"Tawnya" +, +"Tawsha" +, +"Ted" +, +"Tedda" +, +"Teddi" +, +"Teddie" +, +"Teddy" +, +"Tedi" +, +"Tedra" +, +"Teena" +, +"TEirtza" +, +"Teodora" +, +"Tera" +, +"Teresa" +, +"Terese" +, +"Teresina" +, +"Teresita" +, +"Teressa" +, +"Teri" +, +"Teriann" +, +"Terra" +, +"Terri" +, +"Terrie" +, +"Terrijo" +, +"Terry" +, +"Terrye" +, +"Tersina" +, +"Terza" +, +"Tess" +, +"Tessa" +, +"Tessi" +, +"Tessie" +, +"Tessy" +, +"Thalia" +, +"Thea" +, +"Theadora" +, +"Theda" +, +"Thekla" +, +"Thelma" +, +"Theo" +, +"Theodora" +, +"Theodosia" +, +"Theresa" +, +"Therese" +, +"Theresina" +, +"Theresita" +, +"Theressa" +, +"Therine" +, +"Thia" +, +"Thomasa" +, +"Thomasin" +, +"Thomasina" +, +"Thomasine" +, +"Tiena" +, +"Tierney" +, +"Tiertza" +, +"Tiff" +, +"Tiffani" +, +"Tiffanie" +, +"Tiffany" +, +"Tiffi" +, +"Tiffie" +, +"Tiffy" +, +"Tilda" +, +"Tildi" +, +"Tildie" +, +"Tildy" +, +"Tillie" +, +"Tilly" +, +"Tim" +, +"Timi" +, +"Timmi" +, +"Timmie" +, +"Timmy" +, +"Timothea" +, +"Tina" +, +"Tine" +, +"Tiphani" +, +"Tiphanie" +, +"Tiphany" +, +"Tish" +, +"Tisha" +, +"Tobe" +, +"Tobey" +, +"Tobi" +, +"Toby" +, +"Tobye" +, +"Toinette" +, +"Toma" +, +"Tomasina" +, +"Tomasine" +, +"Tomi" +, +"Tommi" +, +"Tommie" +, +"Tommy" +, +"Toni" +, +"Tonia" +, +"Tonie" +, +"Tony" +, +"Tonya" +, +"Tonye" +, +"Tootsie" +, +"Torey" +, +"Tori" +, +"Torie" +, +"Torrie" +, +"Tory" +, +"Tova" +, +"Tove" +, +"Tracee" +, +"Tracey" +, +"Traci" +, +"Tracie" +, +"Tracy" +, +"Trenna" +, +"Tresa" +, +"Trescha" +, +"Tressa" +, +"Tricia" +, +"Trina" +, +"Trish" +, +"Trisha" +, +"Trista" +, +"Trix" +, +"Trixi" +, +"Trixie" +, +"Trixy" +, +"Truda" +, +"Trude" +, +"Trudey" +, +"Trudi" +, +"Trudie" +, +"Trudy" +, +"Trula" +, +"Tuesday" +, +"Twila" +, +"Twyla" +, +"Tybi" +, +"Tybie" +, +"Tyne" +, +"Ula" +, +"Ulla" +, +"Ulrica" +, +"Ulrika" +, +"Ulrikaumeko" +, +"Ulrike" +, +"Umeko" +, +"Una" +, +"Ursa" +, +"Ursala" +, +"Ursola" +, +"Ursula" +, +"Ursulina" +, +"Ursuline" +, +"Uta" +, +"Val" +, +"Valaree" +, +"Valaria" +, +"Vale" +, +"Valeda" +, +"Valencia" +, +"Valene" +, +"Valenka" +, +"Valentia" +, +"Valentina" +, +"Valentine" +, +"Valera" +, +"Valeria" +, +"Valerie" +, +"Valery" +, +"Valerye" +, +"Valida" +, +"Valina" +, +"Valli" +, +"Vallie" +, +"Vally" +, +"Valma" +, +"Valry" +, +"Van" +, +"Vanda" +, +"Vanessa" +, +"Vania" +, +"Vanna" +, +"Vanni" +, +"Vannie" +, +"Vanny" +, +"Vanya" +, +"Veda" +, +"Velma" +, +"Velvet" +, +"Venita" +, +"Venus" +, +"Vera" +, +"Veradis" +, +"Vere" +, +"Verena" +, +"Verene" +, +"Veriee" +, +"Verile" +, +"Verina" +, +"Verine" +, +"Verla" +, +"Verna" +, +"Vernice" +, +"Veronica" +, +"Veronika" +, +"Veronike" +, +"Veronique" +, +"Vevay" +, +"Vi" +, +"Vicki" +, +"Vickie" +, +"Vicky" +, +"Victoria" +, +"Vida" +, +"Viki" +, +"Vikki" +, +"Vikky" +, +"Vilhelmina" +, +"Vilma" +, +"Vin" +, +"Vina" +, +"Vinita" +, +"Vinni" +, +"Vinnie" +, +"Vinny" +, +"Viola" +, +"Violante" +, +"Viole" +, +"Violet" +, +"Violetta" +, +"Violette" +, +"Virgie" +, +"Virgina" +, +"Virginia" +, +"Virginie" +, +"Vita" +, +"Vitia" +, +"Vitoria" +, +"Vittoria" +, +"Viv" +, +"Viva" +, +"Vivi" +, +"Vivia" +, +"Vivian" +, +"Viviana" +, +"Vivianna" +, +"Vivianne" +, +"Vivie" +, +"Vivien" +, +"Viviene" +, +"Vivienne" +, +"Viviyan" +, +"Vivyan" +, +"Vivyanne" +, +"Vonni" +, +"Vonnie" +, +"Vonny" +, +"Vyky" +, +"Wallie" +, +"Wallis" +, +"Walliw" +, +"Wally" +, +"Waly" +, +"Wanda" +, +"Wandie" +, +"Wandis" +, +"Waneta" +, +"Wanids" +, +"Wenda" +, +"Wendeline" +, +"Wendi" +, +"Wendie" +, +"Wendy" +, +"Wendye" +, +"Wenona" +, +"Wenonah" +, +"Whitney" +, +"Wileen" +, +"Wilhelmina" +, +"Wilhelmine" +, +"Wilie" +, +"Willa" +, +"Willabella" +, +"Willamina" +, +"Willetta" +, +"Willette" +, +"Willi" +, +"Willie" +, +"Willow" +, +"Willy" +, +"Willyt" +, +"Wilma" +, +"Wilmette" +, +"Wilona" +, +"Wilone" +, +"Wilow" +, +"Windy" +, +"Wini" +, +"Winifred" +, +"Winna" +, +"Winnah" +, +"Winne" +, +"Winni" +, +"Winnie" +, +"Winnifred" +, +"Winny" +, +"Winona" +, +"Winonah" +, +"Wren" +, +"Wrennie" +, +"Wylma" +, +"Wynn" +, +"Wynne" +, +"Wynnie" +, +"Wynny" +, +"Xaviera" +, +"Xena" +, +"Xenia" +, +"Xylia" +, +"Xylina" +, +"Yalonda" +, +"Yasmeen" +, +"Yasmin" +, +"Yelena" +, +"Yetta" +, +"Yettie" +, +"Yetty" +, +"Yevette" +, +"Ynes" +, +"Ynez" +, +"Yoko" +, +"Yolanda" +, +"Yolande" +, +"Yolane" +, +"Yolanthe" +, +"Yoshi" +, +"Yoshiko" +, +"Yovonnda" +, +"Ysabel" +, +"Yvette" +, +"Yvonne" +, +"Zabrina" +, +"Zahara" +, +"Zandra" +, +"Zaneta" +, +"Zara" +, +"Zarah" +, +"Zaria" +, +"Zarla" +, +"Zea" +, +"Zelda" +, +"Zelma" +, +"Zena" +, +"Zenia" +, +"Zia" +, +"Zilvia" +, +"Zita" +, +"Zitella" +, +"Zoe" +, +"Zola" +, +"Zonda" +, +"Zondra" +, +"Zonnya" +, +"Zora" +, +"Zorah" +, +"Zorana" +, +"Zorina" +, +"Zorine" +, +"Zsa Zsa" +, +"Zsazsa" +, +"Zulema" +, +"Zuzana" +] diff --git a/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NameCell.swift b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NameCell.swift new file mode 100644 index 00000000..d388819e --- /dev/null +++ b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NameCell.swift @@ -0,0 +1,29 @@ +import UIKit +import Utilities + +final class NameCell: LabelCell { + override init(frame: CGRect) { + super.init(frame: frame) + commonInit() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + commonInit() + } + + private func commonInit() { + label.textAlignment = .left + label.font = .preferredFont(forTextStyle: .body) + label.adjustsFontForContentSizeCategory = true + } + + override func prepareForReuse() { + super.prepareForReuse() + label.text = nil + } + + func set(name: String) { + label.text = name + } +} diff --git a/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NameSectionHeaderView.swift b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NameSectionHeaderView.swift new file mode 100644 index 00000000..36f7bb6c --- /dev/null +++ b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NameSectionHeaderView.swift @@ -0,0 +1,54 @@ +import UIKit +import Utilities + +final class NameSectionHeaderView: LabelSupplementaryView { + private var headerPressedHandler: (() -> Void)? + + private lazy var closeIcon = UIImageView(image: .init(systemName: "x.circle")) + + private lazy var gestureRecognizer = UITapGestureRecognizer( + target: self, + action: #selector(headerPressed) + ) + + override init(frame: CGRect) { + super.init(frame: frame) + commonInit() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + commonInit() + } + + private func commonInit() { + addGestureRecognizer(gestureRecognizer) + backgroundColor = .systemGray6 + label.font = .preferredFont(forTextStyle: .title2) + addSubview(closeIcon) + closeIcon.translatesAutoresizingMaskIntoConstraints = false + closeIcon.tintColor = .black + NSLayoutConstraint.activate([ + closeIcon.centerYAnchor.constraint(equalTo: layoutMarginsGuide.centerYAnchor), + closeIcon.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor) + ]) + } + + @objc private func headerPressed() { + headerPressedHandler?() + } + + func set( + title: String, + headerPressedHandler: @escaping () -> Void + ) { + self.label.text = title + self.headerPressedHandler = headerPressedHandler + } + + override func prepareForReuse() { + super.prepareForReuse() + label.text = nil + headerPressedHandler = nil + } +} diff --git a/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesCoordinator+NamesSectionNavigation.swift b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesCoordinator+NamesSectionNavigation.swift new file mode 100644 index 00000000..cdea85f1 --- /dev/null +++ b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesCoordinator+NamesSectionNavigation.swift @@ -0,0 +1,13 @@ +import UIKit + +extension NamesCoordinator: NamesSectionNavigation { + func show(name: String) { + let alertController = UIAlertController( + title: "Someone being choosed", + message: "Amazing \(name) is nominated!", + preferredStyle: .alert + ) + alertController.addAction(UIAlertAction(title: "OK", style: .default)) + navigationController.present(alertController, animated: true) + } +} diff --git a/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesCoordinator+Presentable.swift b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesCoordinator+Presentable.swift new file mode 100644 index 00000000..3d08989f --- /dev/null +++ b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesCoordinator+Presentable.swift @@ -0,0 +1,14 @@ +import UIKit +import Utilities + +extension NamesCoordinator: Presentable { + private func makeViewController() -> UIViewController { + let viewModel = NamesViewModel(navigation: self) + return NamesViewController(viewModel: viewModel) + } + + @discardableResult + public func present(segue: NavigationSegue) -> NavigationSegue.RewindAction { + segue.invoke(with: makeViewController()) + } +} diff --git a/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesCoordinator.swift b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesCoordinator.swift new file mode 100644 index 00000000..1cb03d6f --- /dev/null +++ b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesCoordinator.swift @@ -0,0 +1,9 @@ +import UIKit + +public struct NamesCoordinator { + unowned let navigationController: UINavigationController + + public init(navigationController: UINavigationController) { + self.navigationController = navigationController + } +} diff --git a/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesSectionController.swift b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesSectionController.swift new file mode 100644 index 00000000..5830afa3 --- /dev/null +++ b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesSectionController.swift @@ -0,0 +1,76 @@ +import SectionKit +import UIKit + +final class NamesSectionController: ListSectionController< + NamesSectionViewModelType, + String +> { + override var layoutProvider: SectionLayoutProvider { + let layoutSize = NSCollectionLayoutSize( + widthDimension: .fractionalWidth(1), + heightDimension: .estimated(50) + ) + + let item = NSCollectionLayoutItem(layoutSize: layoutSize) + let layout = NSCollectionLayoutSection( + group: .vertical( + layoutSize: layoutSize, + subitem: item, + count: 1 + ) + ) + let header = NSCollectionLayoutBoundarySupplementaryItem( + layoutSize: .init( + widthDimension: .fractionalWidth(1), + heightDimension: .estimated(30) + ), + elementKind: UICollectionView.elementKindSectionHeader, + alignment: .top + ) + header.pinToVisibleBounds = true + + // Hide the section header if it's collapsed + if !model.isCollapsed { + layout.boundarySupplementaryItems = [header] + } else { + layout.boundarySupplementaryItems = [] + } + return .compositionalLayout( + .init { _ in layout } + ) + } + + override func items(for model: NamesSectionViewModelType) -> [String] { + model.isCollapsed ? [] : model.names + } + + override func cellForItem( + at indexPath: SectionIndexPath, + in context: CollectionViewContext + ) -> UICollectionViewCell { + let cell: NameCell = context.dequeueReusableCell(for: indexPath) + cell.set(name: items[indexPath]) + return cell + } + + override func didSelectItem(at indexPath: SectionIndexPath, in context: CollectionViewContext) { + model.select(name: items[indexPath]) + context.collectionView.deselectItem(at: indexPath.indexInCollectionView, animated: true) + } + + // MARK: - Header + + override func headerView( + at indexPath: SectionIndexPath, + in context: any CollectionViewContext + ) -> UICollectionReusableView { + let header: NameSectionHeaderView = context.dequeueReusableHeaderView(for: indexPath) + header.set(title: model.sectionId) { [weak self] in + guard let self else { return } + self.model.pressCollapse() + // Reload the items + self.items = items(for: self.model) + } + return header + } +} diff --git a/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesSectionViewModel.swift b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesSectionViewModel.swift new file mode 100644 index 00000000..6282844b --- /dev/null +++ b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesSectionViewModel.swift @@ -0,0 +1,46 @@ +import Foundation + +typealias NamesSectionViewModelType = NamesSectionViewModelInputs & NamesSectionViewModelOutputs + +protocol NamesSectionViewModelInputs { + func select(name: String) + func pressCollapse() +} + +protocol NamesSectionViewModelOutputs { + var sectionId: String { get } + var sectionTitle: String { get } + var names: [String] { get } + var isCollapsed: Bool { get } +} + +protocol NamesSectionNavigation { + func show(name: String) +} + +final class NamesSectionViewModel: NamesSectionViewModelType { + private let navigation: NamesSectionNavigation + let sectionId: String + let sectionTitle: String + let names: [String] + private(set) var isCollapsed = false + + init( + sectionTitle: String, + names: [String], + navigation: NamesSectionNavigation + ) { + self.sectionId = sectionTitle + self.sectionTitle = sectionTitle + self.names = names + self.navigation = navigation + } + + func select(name: String) { + navigation.show(name: name) + } + + func pressCollapse() { + isCollapsed.toggle() + } +} diff --git a/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesViewController.swift b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesViewController.swift new file mode 100644 index 00000000..8331b7a0 --- /dev/null +++ b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesViewController.swift @@ -0,0 +1,51 @@ +import UIKit +import SectionKit + +final class NamesViewController: UIViewController { + private let viewModel: NamesViewModelType + + private lazy var collectionView: UICollectionView = { + let layout = SectionKitCompositionalLayout() + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.backgroundColor = .systemBackground + collectionView.alwaysBounceVertical = true + return collectionView + }() + + private lazy var collectionViewAdapter = ListCollectionViewAdapter( + collectionView: collectionView, + dataSource: self + ) + + init(viewModel: NamesViewModelType) { + self.viewModel = viewModel + super.init(nibName: nil, bundle: nil) + } + + @available(*, unavailable) + required internal init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func loadView() { + view = collectionView + } + + override func viewDidLoad() { + super.viewDidLoad() + title = viewModel.title + collectionViewAdapter.invalidateDataSource() + } +} + +extension NamesViewController: ListCollectionViewAdapterDataSource { + internal func sections(for adapter: CollectionViewAdapter) -> [Section] { + viewModel.sections.map { + Section( + id: $0.sectionId, + model: $0, + controller: NamesSectionController(model: $0) + ) + } + } +} diff --git a/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesViewModel.swift b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesViewModel.swift new file mode 100644 index 00000000..91841eaa --- /dev/null +++ b/Example/VanillaSwiftExamples/Sources/VanillaSwiftExamples/Names/NamesViewModel.swift @@ -0,0 +1,48 @@ +import Foundation + +typealias NamesViewModelType = NamesViewModelInputs & NamesViewModelOutputs + +protocol NamesViewModelInputs { } + +internal protocol NamesViewModelOutputs { + var title: String { get } + var sections: [NamesSectionViewModelType] { get } +} + +struct NamesViewModel: NamesViewModelType { + let title = "Names" + let sections: [NamesSectionViewModelType] + + init(navigation: NamesSectionNavigation) { + let namesDictionary: [String: [String]] + + if let url = Bundle.main.url( + forResource: "first-names", + withExtension: "json" + ) { + do { + let data = try Data(contentsOf: url) + let decoder = JSONDecoder() + let firstnames = try decoder.decode([String].self, from: data) + namesDictionary = Dictionary.init(grouping: firstnames, by: { firstname in + firstname.first.map { String($0) } ?? "" + }) + } catch { + print("error:\(error)") + namesDictionary = [:] + } + } else { + namesDictionary = [:] + } + self.sections = namesDictionary.keys + .sorted() + .compactMap { key -> NamesSectionViewModel? in + guard let names = namesDictionary[key] else { return nil } + return NamesSectionViewModel( + sectionTitle: key, + names: names, + navigation: navigation + ) + } + } +} diff --git a/Example/VanillaSwiftExamples/Tests/VanillaSwiftExamplesSnapshotTests/ColorsSectionControllerSnapshotTests.swift b/Example/VanillaSwiftExamples/Tests/VanillaSwiftExamplesSnapshotTests/ColorsSectionControllerSnapshotTests.swift index b1fcc521..584dfd8f 100644 --- a/Example/VanillaSwiftExamples/Tests/VanillaSwiftExamplesSnapshotTests/ColorsSectionControllerSnapshotTests.swift +++ b/Example/VanillaSwiftExamples/Tests/VanillaSwiftExamplesSnapshotTests/ColorsSectionControllerSnapshotTests.swift @@ -3,8 +3,8 @@ import SnapshotTesting import TestUtilities import XCTest -@MainActor final class ColorsSectionControllerSnapshotTests: XCTestCase { + @MainActor func testDefaultViewModel() { let sectionController = ColorsSectionController(model: [.red, .green, .blue]) let container = SectionSnapshotContainer(sectionController: sectionController, width: 375) diff --git a/Example/VanillaSwiftExamples/Tests/VanillaSwiftExamplesSnapshotTests/NumbersSectionControllerSnapshotTests.swift b/Example/VanillaSwiftExamples/Tests/VanillaSwiftExamplesSnapshotTests/NumbersSectionControllerSnapshotTests.swift index 88263016..838c5425 100644 --- a/Example/VanillaSwiftExamples/Tests/VanillaSwiftExamplesSnapshotTests/NumbersSectionControllerSnapshotTests.swift +++ b/Example/VanillaSwiftExamples/Tests/VanillaSwiftExamplesSnapshotTests/NumbersSectionControllerSnapshotTests.swift @@ -3,8 +3,8 @@ import SnapshotTesting import TestUtilities import XCTest -@MainActor final class NumbersSectionControllerSnapshotTests: XCTestCase { + @MainActor func testDefaultViewModel() { let model = NumbersSectionViewModel(numbers: Array(0..<10), navigation: MockNumbersSectionNavigation()) let sectionController = NumbersSectionController(model: model) diff --git a/SectionKit.xcodeproj/project.pbxproj b/SectionKit.xcodeproj/project.pbxproj index c4e95594..4052815b 100644 --- a/SectionKit.xcodeproj/project.pbxproj +++ b/SectionKit.xcodeproj/project.pbxproj @@ -33,9 +33,7 @@ 5A0B777A26B1A81300B054D4 /* MainCollectionViewContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777926B1A81300B054D4 /* MainCollectionViewContextTests.swift */; }; 5A0B777C26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */; }; 5A0B777E26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777D26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift */; }; - 5A0B778026B299FF00B054D4 /* ListSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777F26B299FF00B054D4 /* ListSectionControllerTests.swift */; }; 5A0B778226B2A92C00B054D4 /* SingleItemSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */; }; - 5A0B778426B2AA2000B054D4 /* SingleModelSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778326B2AA2000B054D4 /* SingleModelSectionControllerTests.swift */; }; 5A0B778626B2AB7800B054D4 /* BaseSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */; }; 5A0B778926B3EA4D00B054D4 /* ErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778826B3EA4D00B054D4 /* ErrorTests.swift */; }; 5A31B8B726BAE8A900036A3F /* BaseSectionDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8B526BAE8A300036A3F /* BaseSectionDataSourceTests.swift */; }; @@ -53,8 +51,6 @@ 5A31B8CF26BAE93900036A3F /* BaseSectionDropDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8CE26BAE93900036A3F /* BaseSectionDropDelegateTests.swift */; }; 5A31B8D126BAE94500036A3F /* BaseSectionControllerSectionDropDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8D026BAE94500036A3F /* BaseSectionControllerSectionDropDelegateTests.swift */; }; 5A31B8D326BAE94E00036A3F /* ProtocolDefaultValuesSectionDropDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8D226BAE94E00036A3F /* ProtocolDefaultValuesSectionDropDelegateTests.swift */; }; - 5A31B8D526BAE95700036A3F /* BaseSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8D426BAE95700036A3F /* BaseSectionFlowDelegateTests.swift */; }; - 5A31B8D726BAE96000036A3F /* BaseSectionControllerSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8D626BAE96000036A3F /* BaseSectionControllerSectionFlowDelegateTests.swift */; }; 5A31B8D926BAE96800036A3F /* ProtocolDefaultValuesSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8D826BAE96800036A3F /* ProtocolDefaultValuesSectionFlowDelegateTests.swift */; }; 5A31B8E026BBF32D00036A3F /* UICollectionViewApplyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8DF26BBF32D00036A3F /* UICollectionViewApplyTests.swift */; }; 5A31B8E226BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8E126BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift */; }; @@ -99,10 +95,6 @@ 5AE175EC2667DA3F00D4DCE1 /* SectionIndexPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B22667DA3E00D4DCE1 /* SectionIndexPath.swift */; }; 5AE175ED2667DA3F00D4DCE1 /* SectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B32667DA3E00D4DCE1 /* SectionDelegate.swift */; }; 5AE175EE2667DA3F00D4DCE1 /* BaseSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B52667DA3E00D4DCE1 /* BaseSectionController.swift */; }; - 5AE175EF2667DA3F00D4DCE1 /* ListSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B62667DA3E00D4DCE1 /* ListSectionController.swift */; }; - 5AE175F02667DA3F00D4DCE1 /* SingleItemSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B72667DA3F00D4DCE1 /* SingleItemSectionController.swift */; }; - 5AE175F12667DA3F00D4DCE1 /* SingleModelSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B82667DA3F00D4DCE1 /* SingleModelSectionController.swift */; }; - 5AE175F22667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift */; }; 5AE175F32667DA3F00D4DCE1 /* SectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175BA2667DA3F00D4DCE1 /* SectionController.swift */; }; 5AE175F42667DA3F00D4DCE1 /* SectionDragDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175BB2667DA3F00D4DCE1 /* SectionDragDelegate.swift */; }; 5AE175F52667DA3F00D4DCE1 /* CollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175BD2667DA3F00D4DCE1 /* CollectionViewAdapter.swift */; }; @@ -114,13 +106,9 @@ 5AE175FB2667DA3F00D4DCE1 /* CollectionViewUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C52667DA3F00D4DCE1 /* CollectionViewUpdate.swift */; }; 5AE175FC2667DA3F00D4DCE1 /* ListCollectionViewAdapter+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C72667DA3F00D4DCE1 /* ListCollectionViewAdapter+Convenience.swift */; }; 5AE175FD2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDropDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C82667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDropDelegate.swift */; }; - 5AE175FE2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C92667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift */; }; - 5AE175FF2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CA2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift */; }; 5AE176002667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegateFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CB2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegateFlowLayout.swift */; }; 5AE176012667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CC2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegate.swift */; }; 5AE176022667DA3F00D4DCE1 /* ListCollectionViewAdapter+UIScrollViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CD2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UIScrollViewDelegate.swift */; }; - 5AE176032667DA3F00D4DCE1 /* ListCollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CE2667DA3F00D4DCE1 /* ListCollectionViewAdapter.swift */; }; - 5AE176042667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CF2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift */; }; 5AE176052667DA3F00D4DCE1 /* FoundationDiffingListCollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175D02667DA3F00D4DCE1 /* FoundationDiffingListCollectionViewAdapter.swift */; }; 5AE176062667DA3F00D4DCE1 /* ListCollectionViewAdapterDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175D12667DA3F00D4DCE1 /* ListCollectionViewAdapterDataSource.swift */; }; 5AE176072667DA3F00D4DCE1 /* Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175D22667DA3F00D4DCE1 /* Section.swift */; }; @@ -136,6 +124,20 @@ 5AE176112667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175DD2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift */; }; 5AE1761B2667DA7000D4DCE1 /* SectionIndexPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE176132667DA7000D4DCE1 /* SectionIndexPathTests.swift */; }; 5AE1761E2667DA7000D4DCE1 /* SequenceUniqueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE176182667DA7000D4DCE1 /* SequenceUniqueTests.swift */; }; + D90764CA2BC6B9120083306E /* FoundationDiffingListSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C62BC6B9120083306E /* FoundationDiffingListSectionController.swift */; }; + D90764CB2BC6B9120083306E /* ListSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C72BC6B9120083306E /* ListSectionController.swift */; }; + D90764CC2BC6B9120083306E /* SingleModelSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C82BC6B9120083306E /* SingleModelSectionController.swift */; }; + D90764CD2BC6B9120083306E /* SingleItemSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C92BC6B9120083306E /* SingleItemSectionController.swift */; }; + D90764CF2BC6E8140083306E /* ListSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764CE2BC6E8140083306E /* ListSectionControllerTests.swift */; }; + D91425652BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */; }; + D914257F2BBBF8310005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D914257A2BBBF8130005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift */; }; + D91425852BBBFB840005E8CD /* ListCollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CE2667DA3F00D4DCE1 /* ListCollectionViewAdapter.swift */; }; + D91425872BBBFBA40005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D914257B2BBBF8130005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift */; }; + D93269A22BBBFC2400B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CA2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift */; }; + D93269A32BBBFC2700B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C92667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift */; }; + D93269A42BBBFC2B00B33C32 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CF2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift */; }; + D952494D2BC6EDFB00108510 /* SingleModelSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D952494C2BC6EDFB00108510 /* SingleModelSectionControllerTests.swift */; }; + D9CCE9BF2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9CCE9BE2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -175,9 +177,7 @@ 5A0B777926B1A81300B054D4 /* MainCollectionViewContextTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainCollectionViewContextTests.swift; sourceTree = ""; }; 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewSectionBatchOperationTests.swift; sourceTree = ""; }; 5A0B777D26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewBatchOperationTests.swift; sourceTree = ""; }; - 5A0B777F26B299FF00B054D4 /* ListSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListSectionControllerTests.swift; sourceTree = ""; }; 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleItemSectionControllerTests.swift; sourceTree = ""; }; - 5A0B778326B2AA2000B054D4 /* SingleModelSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleModelSectionControllerTests.swift; sourceTree = ""; }; 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionControllerTests.swift; sourceTree = ""; }; 5A0B778826B3EA4D00B054D4 /* ErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorTests.swift; sourceTree = ""; }; 5A31B8B526BAE8A300036A3F /* BaseSectionDataSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionDataSourceTests.swift; sourceTree = ""; }; @@ -195,8 +195,6 @@ 5A31B8CE26BAE93900036A3F /* BaseSectionDropDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionDropDelegateTests.swift; sourceTree = ""; }; 5A31B8D026BAE94500036A3F /* BaseSectionControllerSectionDropDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionControllerSectionDropDelegateTests.swift; sourceTree = ""; }; 5A31B8D226BAE94E00036A3F /* ProtocolDefaultValuesSectionDropDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtocolDefaultValuesSectionDropDelegateTests.swift; sourceTree = ""; }; - 5A31B8D426BAE95700036A3F /* BaseSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionFlowDelegateTests.swift; sourceTree = ""; }; - 5A31B8D626BAE96000036A3F /* BaseSectionControllerSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionControllerSectionFlowDelegateTests.swift; sourceTree = ""; }; 5A31B8D826BAE96800036A3F /* ProtocolDefaultValuesSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtocolDefaultValuesSectionFlowDelegateTests.swift; sourceTree = ""; }; 5A31B8DF26BBF32D00036A3F /* UICollectionViewApplyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewApplyTests.swift; sourceTree = ""; }; 5A31B8E126BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtocolDefaultValuesSectionControllerTests.swift; sourceTree = ""; }; @@ -244,10 +242,6 @@ 5AE175B22667DA3E00D4DCE1 /* SectionIndexPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionIndexPath.swift; sourceTree = ""; }; 5AE175B32667DA3E00D4DCE1 /* SectionDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionDelegate.swift; sourceTree = ""; }; 5AE175B52667DA3E00D4DCE1 /* BaseSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseSectionController.swift; sourceTree = ""; }; - 5AE175B62667DA3E00D4DCE1 /* ListSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListSectionController.swift; sourceTree = ""; }; - 5AE175B72667DA3F00D4DCE1 /* SingleItemSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleItemSectionController.swift; sourceTree = ""; }; - 5AE175B82667DA3F00D4DCE1 /* SingleModelSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleModelSectionController.swift; sourceTree = ""; }; - 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationDiffingListSectionController.swift; sourceTree = ""; }; 5AE175BA2667DA3F00D4DCE1 /* SectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionController.swift; sourceTree = ""; }; 5AE175BB2667DA3F00D4DCE1 /* SectionDragDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionDragDelegate.swift; sourceTree = ""; }; 5AE175BD2667DA3F00D4DCE1 /* CollectionViewAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewAdapter.swift; sourceTree = ""; }; @@ -281,6 +275,16 @@ 5AE175DD2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleSectionCollectionViewAdapter.swift; sourceTree = ""; }; 5AE176132667DA7000D4DCE1 /* SectionIndexPathTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionIndexPathTests.swift; sourceTree = ""; }; 5AE176182667DA7000D4DCE1 /* SequenceUniqueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SequenceUniqueTests.swift; sourceTree = ""; }; + D90764C62BC6B9120083306E /* FoundationDiffingListSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationDiffingListSectionController.swift; sourceTree = ""; }; + D90764C72BC6B9120083306E /* ListSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListSectionController.swift; sourceTree = ""; }; + D90764C82BC6B9120083306E /* SingleModelSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleModelSectionController.swift; sourceTree = ""; }; + D90764C92BC6B9120083306E /* SingleItemSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleItemSectionController.swift; sourceTree = ""; }; + D90764CE2BC6E8140083306E /* ListSectionControllerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListSectionControllerTests.swift; sourceTree = ""; }; + D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionKitCompositionalLayout.swift; sourceTree = ""; }; + D914257A2BBBF8130005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFlowLayoutSectionFlowDelegateTests.swift; sourceTree = ""; }; + D914257B2BBBF8130005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift; sourceTree = ""; }; + D952494C2BC6EDFB00108510 /* SingleModelSectionControllerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleModelSectionControllerTests.swift; sourceTree = ""; }; + D9CCE9BE2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSCollectionLayoutSection+Empty.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -403,8 +407,8 @@ 5A31B8B426BAE86700036A3F /* SectionFlowDelegate */ = { isa = PBXGroup; children = ( - 5A31B8D426BAE95700036A3F /* BaseSectionFlowDelegateTests.swift */, - 5A31B8D626BAE96000036A3F /* BaseSectionControllerSectionFlowDelegateTests.swift */, + D914257B2BBBF8130005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift */, + D914257A2BBBF8130005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift */, 5A31B8D826BAE96800036A3F /* ProtocolDefaultValuesSectionFlowDelegateTests.swift */, ); path = SectionFlowDelegate; @@ -530,6 +534,7 @@ 5AE175A12667DA3E00D4DCE1 /* Utility */ = { isa = PBXGroup; children = ( + D9CCE9B92BADF6F600EED204 /* CompositionalLayout */, 5AE175A22667DA3E00D4DCE1 /* Sequence+Unique.swift */, 5AE175A52667DA3E00D4DCE1 /* IndexPath+IsValid.swift */, 5AE175A42667DA3E00D4DCE1 /* Move.swift */, @@ -544,8 +549,8 @@ 5AE175A92667DA3E00D4DCE1 /* SectionController */ = { isa = PBXGroup; children = ( + D9CCE9B62BADF2FD00EED204 /* Generic */, 5AE175AD2667DA3E00D4DCE1 /* Update */, - 5AE175B42667DA3E00D4DCE1 /* Generic */, 5AE175B22667DA3E00D4DCE1 /* SectionIndexPath.swift */, 5AE175BA2667DA3F00D4DCE1 /* SectionController.swift */, 5AE175AB2667DA3E00D4DCE1 /* SectionDataSource.swift */, @@ -568,18 +573,6 @@ path = Update; sourceTree = ""; }; - 5AE175B42667DA3E00D4DCE1 /* Generic */ = { - isa = PBXGroup; - children = ( - 5AE175B52667DA3E00D4DCE1 /* BaseSectionController.swift */, - 5AE175B62667DA3E00D4DCE1 /* ListSectionController.swift */, - 5AE175B72667DA3F00D4DCE1 /* SingleItemSectionController.swift */, - 5AE175B82667DA3F00D4DCE1 /* SingleModelSectionController.swift */, - 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift */, - ); - path = Generic; - sourceTree = ""; - }; 5AE175BC2667DA3F00D4DCE1 /* CollectionViewAdapter */ = { isa = PBXGroup; children = ( @@ -661,9 +654,9 @@ 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */, 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */, 5A31B8E126BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift */, - 5A0B777F26B299FF00B054D4 /* ListSectionControllerTests.swift */, + D90764CE2BC6E8140083306E /* ListSectionControllerTests.swift */, 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */, - 5A0B778326B2AA2000B054D4 /* SingleModelSectionControllerTests.swift */, + D952494C2BC6EDFB00108510 /* SingleModelSectionControllerTests.swift */, ); path = SectionController; sourceTree = ""; @@ -698,6 +691,27 @@ path = CollectionViewAdapter; sourceTree = ""; }; + D9CCE9B62BADF2FD00EED204 /* Generic */ = { + isa = PBXGroup; + children = ( + 5AE175B52667DA3E00D4DCE1 /* BaseSectionController.swift */, + D90764C72BC6B9120083306E /* ListSectionController.swift */, + D90764C92BC6B9120083306E /* SingleItemSectionController.swift */, + D90764C82BC6B9120083306E /* SingleModelSectionController.swift */, + D90764C62BC6B9120083306E /* FoundationDiffingListSectionController.swift */, + ); + path = Generic; + sourceTree = ""; + }; + D9CCE9B92BADF6F600EED204 /* CompositionalLayout */ = { + isa = PBXGroup; + children = ( + D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */, + D9CCE9BE2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift */, + ); + path = CompositionalLayout; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -807,10 +821,12 @@ files = ( 5AE176022667DA3F00D4DCE1 /* ListCollectionViewAdapter+UIScrollViewDelegate.swift in Sources */, 5AE175ED2667DA3F00D4DCE1 /* SectionDelegate.swift in Sources */, + D91425852BBBFB840005E8CD /* ListCollectionViewAdapter.swift in Sources */, 5AE175EE2667DA3F00D4DCE1 /* BaseSectionController.swift in Sources */, 5AE1760B2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDropDelegate.swift in Sources */, 5AE176072667DA3F00D4DCE1 /* Section.swift in Sources */, 5AE175DF2667DA3F00D4DCE1 /* CollectionDifference+Changes.swift in Sources */, + D90764CB2BC6B9120083306E /* ListSectionController.swift in Sources */, 5AE175E62667DA3F00D4DCE1 /* SectionDataSource.swift in Sources */, 5AE176002667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegateFlowLayout.swift in Sources */, 5AE1760D2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */, @@ -818,26 +834,25 @@ 5AE175F42667DA3F00D4DCE1 /* SectionDragDelegate.swift in Sources */, 5AE176062667DA3F00D4DCE1 /* ListCollectionViewAdapterDataSource.swift in Sources */, 5AE175F62667DA3F00D4DCE1 /* CollectionViewContext+Size.swift in Sources */, + D90764CA2BC6B9120083306E /* FoundationDiffingListSectionController.swift in Sources */, + D93269A22BBBFC2400B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */, 5AE175F52667DA3F00D4DCE1 /* CollectionViewAdapter.swift in Sources */, 5AE175F32667DA3F00D4DCE1 /* SectionController.swift in Sources */, - 5AE175F22667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift in Sources */, - 5AE176042667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */, + D91425652BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift in Sources */, 5AB6644626A854A9004DC230 /* ErrorHandling.swift in Sources */, 5AE176052667DA3F00D4DCE1 /* FoundationDiffingListCollectionViewAdapter.swift in Sources */, 5AE175E92667DA3F00D4DCE1 /* CollectionViewSectionBatchOperation.swift in Sources */, 5AE175E02667DA3F00D4DCE1 /* Move.swift in Sources */, + D90764CC2BC6B9120083306E /* SingleModelSectionController.swift in Sources */, 5AE175EB2667DA3F00D4DCE1 /* SectionDataSourcePrefetchingDelegate.swift in Sources */, 5AE175EC2667DA3F00D4DCE1 /* SectionIndexPath.swift in Sources */, 5AE1760F2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */, 5AE1760A2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */, - 5AE175FE2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */, - 5AE175F12667DA3F00D4DCE1 /* SingleModelSectionController.swift in Sources */, 5AE175FB2667DA3F00D4DCE1 /* CollectionViewUpdate.swift in Sources */, 5AE175E42667DA3F00D4DCE1 /* Collection+Extensions.swift in Sources */, - 5AE176032667DA3F00D4DCE1 /* ListCollectionViewAdapter.swift in Sources */, 5AE175E12667DA3F00D4DCE1 /* IndexPath+IsValid.swift in Sources */, 5AE175F82667DA3F00D4DCE1 /* MainCollectionViewContext.swift in Sources */, - 5AE175FF2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */, + D9CCE9BF2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift in Sources */, 5AE176102667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+Convenience.swift in Sources */, 5AE175DE2667DA3F00D4DCE1 /* Sequence+Unique.swift in Sources */, 5AB6644426A85463004DC230 /* Error.swift in Sources */, @@ -846,18 +861,19 @@ 5AE175E82667DA3F00D4DCE1 /* CollectionViewContext+CollectionViewSectionUpdate.swift in Sources */, 5AE175EA2667DA3F00D4DCE1 /* CollectionViewSectionUpdate.swift in Sources */, 5AE175F92667DA3F00D4DCE1 /* CollectionViewBatchOperation.swift in Sources */, - 5AE175EF2667DA3F00D4DCE1 /* ListSectionController.swift in Sources */, - 5AE175F02667DA3F00D4DCE1 /* SingleItemSectionController.swift in Sources */, 5AE175FD2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDropDelegate.swift in Sources */, 5AE176092667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDelegate.swift in Sources */, + D93269A32BBBFC2700B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */, 5AE1760C2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UIScrollViewDelegate.swift in Sources */, 5A98000B2678D6BD00378EB5 /* Array+SectionIndexPath.swift in Sources */, 5AE175FA2667DA3F00D4DCE1 /* CollectionViewContext+CollectionViewUpdate.swift in Sources */, 5AE175E72667DA3F00D4DCE1 /* SectionFlowDelegate.swift in Sources */, 5AE175E32667DA3F00D4DCE1 /* UICollectionView+Apply.swift in Sources */, 5AE176012667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegate.swift in Sources */, + D90764CD2BC6B9120083306E /* SingleItemSectionController.swift in Sources */, 5AE1760E2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapterDataSource.swift in Sources */, 5AE176112667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift in Sources */, + D93269A42BBBFC2B00B33C32 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */, 5AE175FC2667DA3F00D4DCE1 /* ListCollectionViewAdapter+Convenience.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -871,12 +887,14 @@ 5A0B775626B0050800B054D4 /* MockSectionDropDelegate.swift in Sources */, 5A0B774B26AEEB3100B054D4 /* SingleSectionCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift in Sources */, 5AB6643026A59626004DC230 /* BaseCollectionViewAdapterUICollectionViewDataSourceTests.swift in Sources */, - 5A31B8D526BAE95700036A3F /* BaseSectionFlowDelegateTests.swift in Sources */, + D91425872BBBFBA40005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift in Sources */, 5A31B8D326BAE94E00036A3F /* ProtocolDefaultValuesSectionDropDelegateTests.swift in Sources */, 5A0B776626B146EC00B054D4 /* ListCollectionViewAdapterUICollectionViewDragDelegateTests.swift in Sources */, 5AA9D96A26AACACF00679D88 /* MockSectionDelegate.swift in Sources */, 5A0B778626B2AB7800B054D4 /* BaseSectionControllerTests.swift in Sources */, 5A0B777026B19EB300B054D4 /* MockListCollectionViewAdapterDataSource.swift in Sources */, + D914257F2BBBF8310005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift in Sources */, + D90764CF2BC6E8140083306E /* ListSectionControllerTests.swift in Sources */, 5A31B8E426BC36C400036A3F /* CollectionViewContextExtensionsTests.swift in Sources */, 5AA9D96E26AAD06100679D88 /* SingleSectionCollectionViewAdapterUICollectionViewDelegateTests.swift in Sources */, 5AE1761E2667DA7000D4DCE1 /* SequenceUniqueTests.swift in Sources */, @@ -887,7 +905,6 @@ 5AB6642926A587AE004DC230 /* CollectionViewContextSizeTests.swift in Sources */, 5A31B8CF26BAE93900036A3F /* BaseSectionDropDelegateTests.swift in Sources */, 5A31B8BF26BAE8EE00036A3F /* BaseSectionControllerSectionDataSourcePrefetchingDelegateTests.swift in Sources */, - 5A0B778426B2AA2000B054D4 /* SingleModelSectionControllerTests.swift in Sources */, 5A0B775926B0069700B054D4 /* BaseCollectionViewAdapterUICollectionViewDropDelegateTests.swift in Sources */, 5A0B776E26B19E8C00B054D4 /* MockSingleSectionCollectionViewAdapterDataSource.swift in Sources */, 5A8D3E5927E8D16200073712 /* MockCollectionViewAdapter.swift in Sources */, @@ -896,7 +913,6 @@ 5A31B8BB26BAE8D400036A3F /* ProtocolDefaultValuesSectionDataSourceTests.swift in Sources */, 5A0B774E26AF0C2100B054D4 /* BaseCollectionViewAdapterUIScrollViewDelegateTests.swift in Sources */, 5AA9D96826AAC9AF00679D88 /* BaseCollectionViewAdapterUICollectionViewDelegateTests.swift in Sources */, - 5A0B778026B299FF00B054D4 /* ListSectionControllerTests.swift in Sources */, 5A0B775B26B006AA00B054D4 /* ListCollectionViewAdapterUICollectionViewDropDelegateTests.swift in Sources */, 5A31B8BD26BAE8E300036A3F /* BaseSectionDataSourcePrefetchingDelegateTests.swift in Sources */, 5A31B8C126BAE8F800036A3F /* ProtocolDefaultValuesSectionDataSourcePrefetchingDelegateTests.swift in Sources */, @@ -919,7 +935,7 @@ 5AA9D96326AAC65200679D88 /* ListCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift in Sources */, 5AE1761B2667DA7000D4DCE1 /* SectionIndexPathTests.swift in Sources */, 5AA9D96C26AAD05400679D88 /* ListCollectionViewAdapterUICollectionViewDelegateTests.swift in Sources */, - 5A31B8D726BAE96000036A3F /* BaseSectionControllerSectionFlowDelegateTests.swift in Sources */, + D952494D2BC6EDFB00108510 /* SingleModelSectionControllerTests.swift in Sources */, 5A31B8C726BAE91300036A3F /* ProtocolDefaultValuesSectionDelegateTests.swift in Sources */, 5A0B776A26B1826100B054D4 /* ListCollectionViewAdapterTests.swift in Sources */, 5A31B8B926BAE8C600036A3F /* BaseSectionControllerSectionDataSourceTests.swift in Sources */, diff --git a/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift b/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift index d98d0429..65398091 100644 --- a/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift +++ b/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift @@ -58,12 +58,20 @@ extension ListCollectionViewAdapter { extension ListCollectionViewAdapter { @inlinable public func flowDelegate(at indexPath: IndexPath) -> SectionFlowDelegate? { - controller(at: indexPath)?.flowDelegate + if #available(iOS 13.0, *) { + return controller(at: indexPath)?.layoutProvider.flowLayoutProvider + } else { + return controller(at: indexPath)?.flowDelegate + } } @inlinable public func flowDelegate(at index: Int) -> SectionFlowDelegate? { - controller(at: index)?.flowDelegate + if #available(iOS 13.0, *) { + return controller(at: index)?.layoutProvider.flowLayoutProvider + } else { + return controller(at: index)?.flowDelegate + } } } diff --git a/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter.swift b/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter.swift index ee54431c..d86535c2 100644 --- a/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter.swift +++ b/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter.swift @@ -49,6 +49,12 @@ open class ListCollectionViewAdapter: NSObject, CollectionViewAdapter { collectionView.dragDelegate = self collectionView.dropDelegate = self } + if #available(iOS 13.0, *), + let layout = collectionView.collectionViewLayout as? SectionKitCompositionalLayout { + layout.sections = { [weak self] in + self?.collectionViewSections ?? [] + } + } } /** @@ -90,6 +96,12 @@ open class ListCollectionViewAdapter: NSObject, CollectionViewAdapter { collectionView.dragDelegate = self collectionView.dropDelegate = self } + if #available(iOS 13.0, *), + let layout = collectionView.collectionViewLayout as? SectionKitCompositionalLayout { + layout.sections = { [weak self] in + self?.collectionViewSections ?? [] + } + } } public let context: CollectionViewContext diff --git a/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift b/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift index e27e473f..a4140864 100644 --- a/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift +++ b/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift @@ -58,12 +58,20 @@ extension SingleSectionCollectionViewAdapter { extension SingleSectionCollectionViewAdapter { @inlinable public func flowDelegate(at indexPath: IndexPath) -> SectionFlowDelegate? { - controller(at: indexPath)?.flowDelegate + if #available(iOS 13.0, *) { + return controller(at: indexPath)?.layoutProvider.flowLayoutProvider + } else { + return controller(at: indexPath)?.flowDelegate + } } @inlinable public func flowDelegate(at index: Int) -> SectionFlowDelegate? { - controller(at: index)?.flowDelegate + if #available(iOS 13.0, *) { + return controller(at: index)?.layoutProvider.flowLayoutProvider + } else { + return controller(at: index)?.flowDelegate + } } } diff --git a/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift b/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift index 7c97544f..7ef4035b 100644 --- a/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift +++ b/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift @@ -2,7 +2,7 @@ import UIKit /** A base implementation of all `SectionController` datasource and delegate protocols. - + Every declaration is marked `open` and can be overridden. */ @MainActor @@ -36,6 +36,9 @@ open class BaseSectionController: SectionController, @available(iOS 11.0, *) open var dropDelegate: SectionDropDelegate? { self } + @available(iOS 13.0, *) + open var layoutProvider: SectionLayoutProvider { .flowLayout(self) } + open func didUpdate(model: Any) { } // MARK: - SectionDataSource @@ -266,40 +269,77 @@ open class BaseSectionController: SectionController, // MARK: - SectionFlowDelegate + @available( + iOS, + introduced: 6.0, + deprecated: 13.0, + message: "Please use the layoutProvider with the flowLayout type" + ) open func sizeForItem( at indexPath: SectionIndexPath, using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.itemSize ?? CGSize(width: 50, height: 50) + layout.flowLayout?.itemSize ?? FlowLayoutConstants.defaultItemSize } + @available( + iOS, + introduced: 6.0, + deprecated: 13.0, + message: "Please use the layoutProvider with the flowLayout type" + ) open func inset(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> UIEdgeInsets { - (layout as? UICollectionViewFlowLayout)?.sectionInset ?? .zero + layout.flowLayout?.sectionInset ?? FlowLayoutConstants.defaultInset } + @available( + iOS, + introduced: 6.0, + deprecated: 13.0, + message: "Please use the layoutProvider with the flowLayout type" + ) open func minimumLineSpacing(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> CGFloat { - (layout as? UICollectionViewFlowLayout)?.minimumLineSpacing ?? 10 + layout.flowLayout?.minimumLineSpacing ?? FlowLayoutConstants.defaultMinimumLineSpacing } + @available( + iOS, + introduced: 6.0, + deprecated: 13.0, + message: "Please use the layoutProvider with the flowLayout type" + ) open func minimumInteritemSpacing( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGFloat { - (layout as? UICollectionViewFlowLayout)?.minimumInteritemSpacing ?? 10 + layout.flowLayout?.minimumInteritemSpacing ?? FlowLayoutConstants.defaultMinimumInteritemSpacing } + @available( + iOS, + introduced: 6.0, + deprecated: 13.0, + message: "Please use the layoutProvider with the flowLayout type" + ) open func referenceSizeForHeader( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.headerReferenceSize ?? .zero + layout.flowLayout?.headerReferenceSize ?? FlowLayoutConstants.defaultHeaderSize } + @available( + iOS, + introduced: 6.0, + deprecated: 13.0, + message: "Please use the layoutProvider with the flowLayout type" + ) open func referenceSizeForFooter( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.footerReferenceSize ?? .zero + layout.flowLayout?.footerReferenceSize ?? FlowLayoutConstants.defaultFooterSize } + } diff --git a/SectionKit/Sources/SectionController/SectionController.swift b/SectionKit/Sources/SectionController/SectionController.swift index 6e155d3b..88cd4834 100644 --- a/SectionKit/Sources/SectionController/SectionController.swift +++ b/SectionKit/Sources/SectionController/SectionController.swift @@ -27,6 +27,9 @@ public protocol SectionController: AnyObject { @available(iOS 11.0, *) var dropDelegate: SectionDropDelegate? { get } + @available(iOS 13.0, *) + var layoutProvider: SectionLayoutProvider { get } + /// The model of this section controller changed. func didUpdate(model: Any) } @@ -45,3 +48,44 @@ extension SectionController { @available(iOS 11.0, *) public var dropDelegate: SectionDropDelegate? { nil } } + +@available(iOS 13.0, *) +public enum SectionLayoutProvider { + case flowLayout(FlowLayoutProvider?) + case compositionalLayout(CompositionalLayoutProvider) +} + +public typealias FlowLayoutProvider = SectionFlowDelegate + +@MainActor +@available(iOS 13.0, *) +public struct CompositionalLayoutProvider { + /// Provide the layout section for the Compositional Layout + /// - Parameters: + /// - layoutEnvironment: the environment value for the layout + /// - Returns: The layout for the section + var layoutSectionProvider: (_ layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection + + public init( + layoutSectionProvider: @escaping (any NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection + ) { + self.layoutSectionProvider = layoutSectionProvider + } +} + +@available(iOS 13.0, *) +public extension SectionLayoutProvider { + var flowLayoutProvider: FlowLayoutProvider? { + guard case .flowLayout(let flowLayoutProvider) = self else { + return nil + } + return flowLayoutProvider + } + + var compositionalLayoutProvider: CompositionalLayoutProvider? { + guard case .compositionalLayout(let compositionalLayoutProvider) = self else { + return nil + } + return compositionalLayoutProvider + } +} diff --git a/SectionKit/Sources/SectionController/SectionFlowDelegate.swift b/SectionKit/Sources/SectionController/SectionFlowDelegate.swift index 49cd338a..b3ae71a5 100644 --- a/SectionKit/Sources/SectionController/SectionFlowDelegate.swift +++ b/SectionKit/Sources/SectionController/SectionFlowDelegate.swift @@ -76,47 +76,62 @@ public protocol SectionFlowDelegate: AnyObject { func referenceSizeForFooter(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> CGSize } +enum FlowLayoutConstants { + static let defaultItemSize = CGSize(width: 50, height: 50) + static let defaultInset: UIEdgeInsets = .zero + static let defaultMinimumLineSpacing: CGFloat = 10 + static let defaultMinimumInteritemSpacing: CGFloat = 10 + static let defaultHeaderSize: CGSize = .zero + static let defaultFooterSize: CGSize = .zero +} + extension SectionFlowDelegate { public func sizeForItem( at indexPath: SectionIndexPath, using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.itemSize ?? CGSize(width: 50, height: 50) + layout.flowLayout?.itemSize ?? FlowLayoutConstants.defaultItemSize } public func inset( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> UIEdgeInsets { - (layout as? UICollectionViewFlowLayout)?.sectionInset ?? .zero + layout.flowLayout?.sectionInset ?? FlowLayoutConstants.defaultInset } public func minimumLineSpacing( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGFloat { - (layout as? UICollectionViewFlowLayout)?.minimumLineSpacing ?? 10 + layout.flowLayout?.minimumLineSpacing ?? FlowLayoutConstants.defaultMinimumLineSpacing } public func minimumInteritemSpacing( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGFloat { - (layout as? UICollectionViewFlowLayout)?.minimumInteritemSpacing ?? 10 + layout.flowLayout?.minimumInteritemSpacing ?? FlowLayoutConstants.defaultMinimumInteritemSpacing } public func referenceSizeForHeader( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.headerReferenceSize ?? .zero + layout.flowLayout?.headerReferenceSize ?? FlowLayoutConstants.defaultHeaderSize } public func referenceSizeForFooter( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.footerReferenceSize ?? .zero + layout.flowLayout?.footerReferenceSize ?? FlowLayoutConstants.defaultFooterSize + } +} + +extension UICollectionViewLayout { + var flowLayout: UICollectionViewFlowLayout? { + self as? UICollectionViewFlowLayout } } diff --git a/SectionKit/Sources/Utility/CompositionalLayout/NSCollectionLayoutSection+Empty.swift b/SectionKit/Sources/Utility/CompositionalLayout/NSCollectionLayoutSection+Empty.swift new file mode 100644 index 00000000..39e68e45 --- /dev/null +++ b/SectionKit/Sources/Utility/CompositionalLayout/NSCollectionLayoutSection+Empty.swift @@ -0,0 +1,18 @@ +import UIKit + +@available(iOS 13.0, *) +extension NSCollectionLayoutSection { + static let empty: NSCollectionLayoutSection = { + let layoutSize = NSCollectionLayoutSize( + widthDimension: .absolute(0), + heightDimension: .absolute(0) + ) + return NSCollectionLayoutSection( + group: .vertical( + layoutSize: layoutSize, + subitem: .init(layoutSize: layoutSize), + count: 1 + ) + ) + }() +} diff --git a/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift b/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift new file mode 100644 index 00000000..d507b952 --- /dev/null +++ b/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift @@ -0,0 +1,51 @@ +import UIKit + +/// This compositional layout is designed for the section kit. +/// It ensures that the layout provider utilizes the layout section provided by the compositional layout section controller. +@MainActor +@available(iOS 13.0, *) +final public class SectionKitCompositionalLayout: UICollectionViewCompositionalLayout { + // Use internally to bridge the sections from the adapter to the section provider. + var sections: (() -> [Section])? + + public init() { + var sections: (() -> [Section])? + super.init { index, environment in + guard let sections = sections?() else { + assertionFailure("The section update closure doesn't set up correctly, please use the `CollectionViewAdapter`") + return .empty + } + guard sections.count > index else { + assertionFailure("Section index out of bound") + return .empty + } + guard case .compositionalLayout(let provider) = sections[index].controller.layoutProvider else { + let sectionType = String(describing: type(of: sections[index].controller)) + assertionFailure("Please set the layout provider with `CompositionalLayoutProvider` in \(sectionType)") + return .empty + } + return provider.layoutSectionProvider(environment) + } + sections = { [weak self] in + self?.sections?() ?? [] + } + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @available(*, unavailable) + override init( + sectionProvider: @escaping UICollectionViewCompositionalLayoutSectionProvider, + configuration: UICollectionViewCompositionalLayoutConfiguration + ) { + fatalError("init(sectionProvider:configuration:) has not been implemented") + } + + @available(*, unavailable) + override init(sectionProvider: @escaping UICollectionViewCompositionalLayoutSectionProvider) { + fatalError("init(sectionProvider:) has not been implemented") + } +} diff --git a/SectionKit/Tests/CollectionViewAdapter/CollectionViewContext/CollectionViewContextExtensionsTests.swift b/SectionKit/Tests/CollectionViewAdapter/CollectionViewContext/CollectionViewContextExtensionsTests.swift index 1a2a862c..3fcebf11 100644 --- a/SectionKit/Tests/CollectionViewAdapter/CollectionViewContext/CollectionViewContextExtensionsTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/CollectionViewContext/CollectionViewContextExtensionsTests.swift @@ -1,16 +1,31 @@ @testable import SectionKit import XCTest -@MainActor -internal final class CollectionViewContextExtensionsTests: XCTestCase { - // MARK: - dequeueReusableCell +final class CollectionViewContextExtensionsTests: XCTestCase { + private var context: MockCollectionViewContext! - internal func testDequeueReusableCellForIndexPathWithImplicitType() { - let testExpectation = expectation(description: "Should invoke dequeueReusableCell") - let context = MockCollectionViewContext( - collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), + @MainActor + override func setUp() { + super.setUp() + context = MockCollectionViewContext( + collectionView: UICollectionView( + frame: .zero, + collectionViewLayout: UICollectionViewFlowLayout() + ), errorHandler: MockErrorHandler() ) + } + + override func tearDown() { + context = nil + super.tearDown() + } + + // MARK: - dequeueReusableCell + + @MainActor + func testDequeueReusableCellForIndexPathWithImplicitType() { + let testExpectation = expectation(description: "Should invoke dequeueReusableCell") context._dequeueReusableCell = { cellType, indexPath in XCTAssert(cellType === MockCollectionViewCell.self) XCTAssertEqual(indexPath, IndexPath(item: 0, section: 0)) @@ -21,12 +36,9 @@ internal final class CollectionViewContextExtensionsTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableCellForSectionIndexPathWithExplicitType() { + @MainActor + func testDequeueReusableCellForSectionIndexPathWithExplicitType() { let testExpectation = expectation(description: "Should invoke dequeueReusableCell") - let context = MockCollectionViewContext( - collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), - errorHandler: MockErrorHandler() - ) context._dequeueReusableCell = { cellType, indexPath in XCTAssert(cellType === MockCollectionViewCell.self) XCTAssertEqual(indexPath, IndexPath(item: 0, section: 0)) @@ -37,12 +49,9 @@ internal final class CollectionViewContextExtensionsTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableCellForSectionIndexPathWithImplicitType() { + @MainActor + func testDequeueReusableCellForSectionIndexPathWithImplicitType() { let testExpectation = expectation(description: "Should invoke dequeueReusableCell") - let context = MockCollectionViewContext( - collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), - errorHandler: MockErrorHandler() - ) context._dequeueReusableCell = { cellType, indexPath in XCTAssert(cellType === MockCollectionViewCell.self) XCTAssertEqual(indexPath, IndexPath(item: 0, section: 0)) @@ -55,12 +64,9 @@ internal final class CollectionViewContextExtensionsTests: XCTestCase { // MARK: - dequeueReusableHeaderView - internal func testDequeueReusableHeaderViewForIndexPathWithImplicitType() { + @MainActor + func testDequeueReusableHeaderViewForIndexPathWithImplicitType() { let testExpectation = expectation(description: "Should invoke dequeueReusableHeaderView") - let context = MockCollectionViewContext( - collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), - errorHandler: MockErrorHandler() - ) context._dequeueReusableHeaderView = { cellType, indexPath in XCTAssert(cellType === MockCollectionReusableView.self) XCTAssertEqual(indexPath, IndexPath(item: 0, section: 0)) @@ -71,12 +77,9 @@ internal final class CollectionViewContextExtensionsTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableHeaderViewForSectionIndexPathWithExplicitType() { + @MainActor + func testDequeueReusableHeaderViewForSectionIndexPathWithExplicitType() { let testExpectation = expectation(description: "Should invoke dequeueReusableHeaderView") - let context = MockCollectionViewContext( - collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), - errorHandler: MockErrorHandler() - ) context._dequeueReusableHeaderView = { cellType, indexPath in XCTAssert(cellType === MockCollectionReusableView.self) XCTAssertEqual(indexPath, IndexPath(item: 0, section: 0)) @@ -87,12 +90,9 @@ internal final class CollectionViewContextExtensionsTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableHeaderViewForSectionIndexPathWithImplicitType() { + @MainActor + func testDequeueReusableHeaderViewForSectionIndexPathWithImplicitType() { let testExpectation = expectation(description: "Should invoke dequeueReusableHeaderView") - let context = MockCollectionViewContext( - collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), - errorHandler: MockErrorHandler() - ) context._dequeueReusableHeaderView = { cellType, indexPath in XCTAssert(cellType === MockCollectionReusableView.self) XCTAssertEqual(indexPath, IndexPath(item: 0, section: 0)) @@ -105,12 +105,9 @@ internal final class CollectionViewContextExtensionsTests: XCTestCase { // MARK: - dequeueReusableFooterView - internal func testDequeueReusableFooterViewForIndexPathWithImplicitType() { + @MainActor + func testDequeueReusableFooterViewForIndexPathWithImplicitType() { let testExpectation = expectation(description: "Should invoke dequeueReusableFooterView") - let context = MockCollectionViewContext( - collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), - errorHandler: MockErrorHandler() - ) context._dequeueReusableFooterView = { cellType, indexPath in XCTAssert(cellType === MockCollectionReusableView.self) XCTAssertEqual(indexPath, IndexPath(item: 0, section: 0)) @@ -121,12 +118,9 @@ internal final class CollectionViewContextExtensionsTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableFooterViewForSectionIndexPathWithExplicitType() { + @MainActor + func testDequeueReusableFooterViewForSectionIndexPathWithExplicitType() { let testExpectation = expectation(description: "Should invoke dequeueReusableFooterView") - let context = MockCollectionViewContext( - collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), - errorHandler: MockErrorHandler() - ) context._dequeueReusableFooterView = { cellType, indexPath in XCTAssert(cellType === MockCollectionReusableView.self) XCTAssertEqual(indexPath, IndexPath(item: 0, section: 0)) @@ -137,12 +131,9 @@ internal final class CollectionViewContextExtensionsTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableFooterViewForSectionIndexPathWithImplicitType() { + @MainActor + func testDequeueReusableFooterViewForSectionIndexPathWithImplicitType() { let testExpectation = expectation(description: "Should invoke dequeueReusableFooterView") - let context = MockCollectionViewContext( - collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), - errorHandler: MockErrorHandler() - ) context._dequeueReusableFooterView = { cellType, indexPath in XCTAssert(cellType === MockCollectionReusableView.self) XCTAssertEqual(indexPath, IndexPath(item: 0, section: 0)) diff --git a/SectionKit/Tests/CollectionViewAdapter/CollectionViewContext/CollectionViewContextSizeTests.swift b/SectionKit/Tests/CollectionViewAdapter/CollectionViewContext/CollectionViewContextSizeTests.swift index 7f8e60ce..ff4d96e7 100644 --- a/SectionKit/Tests/CollectionViewAdapter/CollectionViewContext/CollectionViewContextSizeTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/CollectionViewContext/CollectionViewContextSizeTests.swift @@ -1,9 +1,9 @@ @testable import SectionKit import XCTest -@MainActor -internal final class CollectionViewContextSizeTests: XCTestCase { - internal func testContainerSize() { +final class CollectionViewContextSizeTests: XCTestCase { + @MainActor + func testContainerSize() { let rect = CGRect(x: 1, y: 2, width: 4, height: 8) let collectionView = UICollectionView(frame: rect, collectionViewLayout: UICollectionViewFlowLayout()) let context = MainCollectionViewContext( @@ -14,7 +14,8 @@ internal final class CollectionViewContextSizeTests: XCTestCase { XCTAssertEqual(context.containerSize, rect.size) } - internal func testCustomContainerInset() { + @MainActor + func testCustomContainerInset() { let insets = UIEdgeInsets(top: 1, left: 2, bottom: 4, right: 8) let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) collectionView.contentInset = insets @@ -26,7 +27,8 @@ internal final class CollectionViewContextSizeTests: XCTestCase { XCTAssertEqual(context.customContainerInset, insets) } - internal func testAdjustedContainerInset() { + @MainActor + func testAdjustedContainerInset() { let insets = UIEdgeInsets(top: 1, left: 2, bottom: 4, right: 8) let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) collectionView.contentInset = insets @@ -38,7 +40,8 @@ internal final class CollectionViewContextSizeTests: XCTestCase { XCTAssertEqual(context.adjustedContainerInset, insets) } - internal func testInsetContainerSize() { + @MainActor + func testInsetContainerSize() { let rect = CGRect(x: 16, y: 32, width: 64, height: 128) let insets = UIEdgeInsets(top: 1, left: 2, bottom: 4, right: 8) let collectionView = UICollectionView(frame: rect, collectionViewLayout: UICollectionViewFlowLayout()) diff --git a/SectionKit/Tests/CollectionViewAdapter/CollectionViewContext/MainCollectionViewContextTests.swift b/SectionKit/Tests/CollectionViewAdapter/CollectionViewContext/MainCollectionViewContextTests.swift index e70c8554..94849d55 100644 --- a/SectionKit/Tests/CollectionViewAdapter/CollectionViewContext/MainCollectionViewContextTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/CollectionViewContext/MainCollectionViewContextTests.swift @@ -1,9 +1,9 @@ @testable import SectionKit import XCTest -@MainActor -internal final class MainCollectionViewContextTests: XCTestCase { - internal func testAdapterIsWeakReferenced() { +final class MainCollectionViewContextTests: XCTestCase { + @MainActor + func testAdapterIsWeakReferenced() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let context = MainCollectionViewContext( viewController: nil, @@ -16,7 +16,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { XCTAssertNil(context.adapter) } - internal func testViewControllerIsWeakReferenced() { + @MainActor + func testViewControllerIsWeakReferenced() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let context = MainCollectionViewContext( viewController: UIViewController(), @@ -26,7 +27,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { XCTAssertNil(context.viewController) } - internal func testApplySectionUpdate() { + @MainActor + func testApplySectionUpdate() { let collectionViewExpectation = expectation(description: "reloadData should be invoked") let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) collectionView._reloadData = collectionViewExpectation.fulfill @@ -52,7 +54,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testApplySectionUpdateWhenAdapterIsNotSetThenReloadDataIsCalled() { + @MainActor + func testApplySectionUpdateWhenAdapterIsNotSetThenReloadDataIsCalled() { let errorExpectation = expectation(description: "The errorHandler should be invoked") let collectionViewExpectation = expectation(description: "reloadData should be invoked") let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) @@ -78,7 +81,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testApplySectionUpdateWhenSectionControllerIsNotPartOfTheAdapterThenReloadDataIsCalled() { + @MainActor + func testApplySectionUpdateWhenSectionControllerIsNotPartOfTheAdapterThenReloadDataIsCalled() { let errorExpectation = expectation(description: "The errorHandler should be invoked") let collectionViewExpectation = expectation(description: "reloadData should be invoked") let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) @@ -106,7 +110,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableCellWhenCellIsNotRegisteredYet() { + @MainActor + func testDequeueReusableCellWhenCellIsNotRegisteredYet() { let registerExpectation = expectation(description: "The cell should be registered") let dequeueExpectation = expectation(description: "The cell should be dequeued") let mockIndexPath = IndexPath(item: 1, section: 2) @@ -137,7 +142,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableCellWhenCellIsAlreadyRegistered() { + @MainActor + func testDequeueReusableCellWhenCellIsAlreadyRegistered() { let registerExpectation = expectation(description: "The cell should not be registered") registerExpectation.fulfill() let dequeueExpectation = expectation(description: "The cell should be dequeued") @@ -168,7 +174,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableCellWhenInvalidCellIsRegistered() { + @MainActor + func testDequeueReusableCellWhenInvalidCellIsRegistered() { let errorExpectation = expectation(description: "The errorHandler should be invoked") let dequeueExpectation = expectation(description: "The cell should be dequeued") let mockIndexPath = IndexPath(item: 1, section: 2) @@ -202,7 +209,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableHeaderViewWhenHeaderViewIsNotRegisteredYet() { + @MainActor + func testDequeueReusableHeaderViewWhenHeaderViewIsNotRegisteredYet() { let registerExpectation = expectation(description: "The header view should be registered") let dequeueExpectation = expectation(description: "The header view should be dequeued") let mockIndexPath = IndexPath(item: 1, section: 2) @@ -235,7 +243,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableHeaderViewWhenHeaderViewIsAlreadyRegistered() { + @MainActor + func testDequeueReusableHeaderViewWhenHeaderViewIsAlreadyRegistered() { let registerExpectation = expectation(description: "The header view should not be registered") registerExpectation.fulfill() let dequeueExpectation = expectation(description: "The header view should be dequeued") @@ -267,7 +276,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableHeaderViewWhenInvalidHeaderViewIsRegistered() { + @MainActor + func testDequeueReusableHeaderViewWhenInvalidHeaderViewIsRegistered() { let errorExpectation = expectation(description: "The errorHandler should be invoked") let dequeueExpectation = expectation(description: "The header view should be dequeued") let mockIndexPath = IndexPath(item: 1, section: 2) @@ -302,7 +312,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableFooterViewWhenFooterViewIsNotRegisteredYet() { + @MainActor + func testDequeueReusableFooterViewWhenFooterViewIsNotRegisteredYet() { let registerExpectation = expectation(description: "The footer view should be registered") let dequeueExpectation = expectation(description: "The footer view should be dequeued") let mockIndexPath = IndexPath(item: 1, section: 2) @@ -335,7 +346,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableFooterViewWhenFooterViewIsAlreadyRegistered() { + @MainActor + func testDequeueReusableFooterViewWhenFooterViewIsAlreadyRegistered() { let registerExpectation = expectation(description: "The footer view should not be registered") registerExpectation.fulfill() let dequeueExpectation = expectation(description: "The footer view should be dequeued") @@ -367,7 +379,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testDequeueReusableFooterViewWhenInvalidFooterViewIsRegistered() { + @MainActor + func testDequeueReusableFooterViewWhenInvalidFooterViewIsRegistered() { let errorExpectation = expectation(description: "The errorHandler should be invoked") let dequeueExpectation = expectation(description: "The footer view should be dequeued") let mockIndexPath = IndexPath(item: 1, section: 2) @@ -402,7 +415,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testSectionControllerWithAdjustedIndexPath() { + @MainActor + func testSectionControllerWithAdjustedIndexPath() { let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let context = MainCollectionViewContext( viewController: nil, @@ -423,7 +437,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { XCTAssertEqual(actual?.1.indexInCollectionView, indexPath) } - internal func testSectionControllerWithAdjustedIndexPathWhenSectionDoesNotExist() { + @MainActor + func testSectionControllerWithAdjustedIndexPathWhenSectionDoesNotExist() { let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let context = MainCollectionViewContext( viewController: nil, @@ -435,7 +450,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { XCTAssertNil(context.sectionControllerWithAdjustedIndexPath(for: IndexPath(item: 0, section: 0))) } - internal func testSectionControllerWithAdjustedIndexPathWhenAdapterIsNotSet() { + @MainActor + func testSectionControllerWithAdjustedIndexPathWhenAdapterIsNotSet() { let errorExpectation = expectation(description: "The errorHandler should be invoked") let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let context = MainCollectionViewContext( @@ -454,7 +470,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testIndexOfControllerWhenAdapterIsNotSet() { + @MainActor + func testIndexOfControllerWhenAdapterIsNotSet() { let errorExpectation = expectation(description: "The errorHandler should be invoked") let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let context = MainCollectionViewContext( @@ -473,7 +490,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testIndexOfControllerThatIsNotPartOfTheContext() { + @MainActor + func testIndexOfControllerThatIsNotPartOfTheContext() { let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = MockCollectionViewAdapter() adapter._sections = { [] } @@ -486,7 +504,8 @@ internal final class MainCollectionViewContextTests: XCTestCase { XCTAssertNil(context.index(of: MockSectionController())) } - internal func testIndexOfControllerThatIsPartOfTheContext() { + @MainActor + func testIndexOfControllerThatIsPartOfTheContext() { let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let controller = MockSectionController() let adapter = MockCollectionViewAdapter() diff --git a/SectionKit/Tests/CollectionViewAdapter/ListCollectionViewAdapterTests.swift b/SectionKit/Tests/CollectionViewAdapter/ListCollectionViewAdapterTests.swift index e2edd149..9362dac9 100644 --- a/SectionKit/Tests/CollectionViewAdapter/ListCollectionViewAdapterTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/ListCollectionViewAdapterTests.swift @@ -1,11 +1,11 @@ @testable import SectionKit import XCTest -@MainActor -internal final class ListCollectionViewAdapterTests: XCTestCase { +final class ListCollectionViewAdapterTests: XCTestCase { // MARK: - Init with datasource - internal func testInitWithDataSourceSetsDataSource() { + @MainActor + func testInitWithDataSourceSetsDataSource() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [] } let adapter = ListCollectionViewAdapter( @@ -15,7 +15,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.dataSource === dataSource) } - internal func testInitWithDataSourceSetsViewController() { + @MainActor + func testInitWithDataSourceSetsViewController() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [] } let viewController = UIViewController() @@ -27,7 +28,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.context.viewController === viewController) } - internal func testInitWithDataSourceSetsScrollViewDelegate() { + @MainActor + func testInitWithDataSourceSetsScrollViewDelegate() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [] } let scrollViewDelegate = MockScrollViewDelegate() @@ -39,7 +41,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.scrollViewDelegate === scrollViewDelegate) } - internal func testInitWithDataSourceSetsErrorHandler() { + @MainActor + func testInitWithDataSourceSetsErrorHandler() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [] } let errorHandler = MockErrorHandler() @@ -51,7 +54,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.context.errorHandler is MockErrorHandler) } - internal func testInitWithDataSourceRetrievesInitialSections() { + @MainActor + func testInitWithDataSourceRetrievesInitialSections() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: MockSectionController()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [section] } @@ -63,7 +67,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.sections.first === section) } - internal func testInitWithDataSourceSetsContextOnInitialSections() { + @MainActor + func testInitWithDataSourceSetsContextOnInitialSections() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: MockSectionController()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [section] } @@ -74,7 +79,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(section.controller.context === adapter.context) } - internal func testInitWithDataSourceSetsCollectionViewDataSourceToSelf() { + @MainActor + func testInitWithDataSourceSetsCollectionViewDataSourceToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [] } let adapter = ListCollectionViewAdapter( @@ -84,8 +90,9 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.dataSource === adapter) } + @MainActor @available(iOS 10.0, *) - internal func testInitWithDataSourceSetsCollectionViewDataSourcePrefetchingToSelf() { + func testInitWithDataSourceSetsCollectionViewDataSourcePrefetchingToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [] } let adapter = ListCollectionViewAdapter( @@ -95,8 +102,9 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.prefetchDataSource === adapter) } + @MainActor @available(iOS 10.0, *) - internal func testInitWithDataSourceEnablesDataSourcePrefetchingOnCollectionView() { + func testInitWithDataSourceEnablesDataSourcePrefetchingOnCollectionView() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [] } let _ = ListCollectionViewAdapter( @@ -106,7 +114,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.isPrefetchingEnabled) } - internal func testInitWithDataSourceSetsCollectionViewDelegateToSelf() { + @MainActor + func testInitWithDataSourceSetsCollectionViewDelegateToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [] } let adapter = ListCollectionViewAdapter( @@ -116,8 +125,9 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.delegate === adapter) } + @MainActor @available(iOS 11.0, *) - internal func testInitWithDataSourceSetsCollectionViewDragDelegateToSelf() { + func testInitWithDataSourceSetsCollectionViewDragDelegateToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [] } let adapter = ListCollectionViewAdapter( @@ -127,8 +137,9 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.dragDelegate === adapter) } + @MainActor @available(iOS 11.0, *) - internal func testInitWithDataSourceSetsCollectionViewDropDelegateToSelf() { + func testInitWithDataSourceSetsCollectionViewDropDelegateToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [] } let adapter = ListCollectionViewAdapter( @@ -138,7 +149,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.dropDelegate === adapter) } - internal func testInitWithDataSourceSetsContextAdapterToSelf() { + @MainActor + func testInitWithDataSourceSetsContextAdapterToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockListCollectionViewAdapterDataSource { _ in [] } let adapter = ListCollectionViewAdapter( @@ -150,7 +162,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { // MARK: - Init with sections - internal func testInitWithSectionsDoesNotSetDataSource() { + @MainActor + func testInitWithSectionsDoesNotSetDataSource() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter( collectionView: collectionView, @@ -159,7 +172,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssertNil(adapter.dataSource) } - internal func testInitWithSectionsSetsViewController() { + @MainActor + func testInitWithSectionsSetsViewController() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let viewController = UIViewController() let adapter = ListCollectionViewAdapter( @@ -170,7 +184,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.context.viewController === viewController) } - internal func testInitWithSectionsSetsScrollViewDelegate() { + @MainActor + func testInitWithSectionsSetsScrollViewDelegate() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let scrollViewDelegate = MockScrollViewDelegate() let adapter = ListCollectionViewAdapter( @@ -181,7 +196,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.scrollViewDelegate === scrollViewDelegate) } - internal func testInitWithSectionsSetsErrorHandler() { + @MainActor + func testInitWithSectionsSetsErrorHandler() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let errorHandler = MockErrorHandler() let adapter = ListCollectionViewAdapter( @@ -192,7 +208,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.context.errorHandler is MockErrorHandler) } - internal func testInitWithSectionsSetsInitialSections() { + @MainActor + func testInitWithSectionsSetsInitialSections() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: MockSectionController()) let adapter = ListCollectionViewAdapter( @@ -203,7 +220,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.sections.first === section) } - internal func testInitWithSectionsSetsContextOnInitialSections() { + @MainActor + func testInitWithSectionsSetsContextOnInitialSections() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: MockSectionController()) let adapter = ListCollectionViewAdapter( @@ -213,7 +231,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(section.controller.context === adapter.context) } - internal func testInitWithSectionsSetsCollectionViewDataSourceToSelf() { + @MainActor + func testInitWithSectionsSetsCollectionViewDataSourceToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter( collectionView: collectionView, @@ -222,8 +241,9 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.dataSource === adapter) } + @MainActor @available(iOS 10.0, *) - internal func testInitWithSectionsSetsCollectionViewDataSourcePrefetchingToSelf() { + func testInitWithSectionsSetsCollectionViewDataSourcePrefetchingToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter( collectionView: collectionView, @@ -232,8 +252,9 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.prefetchDataSource === adapter) } + @MainActor @available(iOS 10.0, *) - internal func testInitWithSectionsEnablesDataSourcePrefetchingOnCollectionView() { + func testInitWithSectionsEnablesDataSourcePrefetchingOnCollectionView() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let _ = ListCollectionViewAdapter( collectionView: collectionView, @@ -242,7 +263,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.isPrefetchingEnabled) } - internal func testInitWithSectionsSetsCollectionViewDelegateToSelf() { + @MainActor + func testInitWithSectionsSetsCollectionViewDelegateToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter( collectionView: collectionView, @@ -251,8 +273,9 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.delegate === adapter) } + @MainActor @available(iOS 11.0, *) - internal func testInitWithSectionsSetsCollectionViewDragDelegateToSelf() { + func testInitWithSectionsSetsCollectionViewDragDelegateToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter( collectionView: collectionView, @@ -261,8 +284,9 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.dragDelegate === adapter) } + @MainActor @available(iOS 11.0, *) - internal func testInitWithSectionsSetsCollectionViewDropDelegateToSelf() { + func testInitWithSectionsSetsCollectionViewDropDelegateToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter( collectionView: collectionView, @@ -271,7 +295,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.dropDelegate === adapter) } - internal func testInitWithSectionsSetsContextAdapterToSelf() { + @MainActor + func testInitWithSectionsSetsContextAdapterToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter( collectionView: collectionView, @@ -282,7 +307,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { // MARK: - Weak references - internal func testDataSourceIsWeakReferenced() { + @MainActor + func testDataSourceIsWeakReferenced() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter( collectionView: collectionView, @@ -291,7 +317,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssertNil(adapter.dataSource) } - internal func testViewControllerIsWeakReferenced() { + @MainActor + func testViewControllerIsWeakReferenced() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter( collectionView: collectionView, @@ -300,7 +327,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssertNil(adapter.context.viewController) } - internal func testScrollViewDelegateIsWeakReferenced() { + @MainActor + func testScrollViewDelegateIsWeakReferenced() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter( collectionView: collectionView, @@ -311,7 +339,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { // MARK: - Setting CollectionViewSections - internal func testSetCollectionViewSectionsUpdatesContextOnSectionController() { + @MainActor + func testSetCollectionViewSectionsUpdatesContextOnSectionController() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let initialSection = Section(id: "", model: "", controller: MockSectionController()) let adapter = ListCollectionViewAdapter( @@ -324,7 +353,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(newSection.controller.context === adapter.context) } - internal func testInitialSectionsFiltersDuplicateSectionsAndInvokeErrorHandler() { + @MainActor + func testInitialSectionsFiltersDuplicateSectionsAndInvokeErrorHandler() { let testExpectation = expectation(description: "Should invoke errorHandler") let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let firstSection = Section(id: "", model: "", controller: MockSectionController()) @@ -347,7 +377,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testSectionsPropertyFiltersDuplicateSectionsAndInvokesErrorHandler() { + @MainActor + func testSectionsPropertyFiltersDuplicateSectionsAndInvokesErrorHandler() { let testExpectation = expectation(description: "Should invoke errorHandler") let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let firstSection = Section(id: "", model: "", controller: MockSectionController()) @@ -371,7 +402,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testSectionsPropertyFiltersDuplicateSectionsAndInvokesDidUpdateOnlyOnce() { + @MainActor + func testSectionsPropertyFiltersDuplicateSectionsAndInvokesDidUpdateOnlyOnce() { let didUpdateExpectation = expectation(description: "Should invoke SectionController.didUpdate exactly once") let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let sectionId = "test" @@ -408,7 +440,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testSettingTheDataSourceRetrievesTheListOfSections() { + @MainActor + func testSettingTheDataSourceRetrievesTheListOfSections() { let testExpectation = expectation(description: "Should invoke dataSource") let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: MockSectionController()) @@ -423,7 +456,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testUpdatingTheSectionsReusesSectionControllersWithTheSameId() { + @MainActor + func testUpdatingTheSectionsReusesSectionControllersWithTheSameId() { let testExpectation = expectation(description: "Should invoke didUpdate on the first SectionController") let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let firstSection = Section(id: "section", model: "1", controller: { @@ -448,7 +482,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testUpdatingTheSectionsCalculatesAnUpdate() { + @MainActor + func testUpdatingTheSectionsCalculatesAnUpdate() { let testExpectation = expectation(description: "Should invoke calculateUpdate on the adapter") let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let firstSection = Section(id: "section", model: "1", controller: { @@ -491,7 +526,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testCallingInvalidateDataSourceRetrievesTheListOfSections() { + @MainActor + func testCallingInvalidateDataSourceRetrievesTheListOfSections() { let testExpectation = expectation(description: "Should invoke dataSource") testExpectation.expectedFulfillmentCount = 2 let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) @@ -512,7 +548,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testResettingDataSourceDoesNotRetrieveTheListOfSectionsAgain() { + @MainActor + func testResettingDataSourceDoesNotRetrieveTheListOfSectionsAgain() { let testExpectation = expectation(description: "Should invoke dataSource") let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: { @@ -534,7 +571,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { // MARK: - calculateUpdate - internal func testCalculateUpdateReloadsData() throws { + @MainActor + func testCalculateUpdateReloadsData() throws { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter(collectionView: collectionView) let update = try XCTUnwrap(adapter.calculateUpdate(from: [], to: [])) @@ -547,7 +585,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(update.shouldReload(batchOperation)) } - internal func testCalculateUpdateHasCorrectData() throws { + @MainActor + func testCalculateUpdateHasCorrectData() throws { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter(collectionView: collectionView) let section = Section(id: "1", model: "", controller: MockSectionController()) @@ -563,7 +602,8 @@ internal final class ListCollectionViewAdapterTests: XCTestCase { XCTAssert(batchOperation.data.first === section) } - internal func testCalculateUpdateSetDataSetsCollectionViewSection() throws { + @MainActor + func testCalculateUpdateSetDataSetsCollectionViewSection() throws { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = ListCollectionViewAdapter(collectionView: collectionView) let section = Section(id: "1", model: "", controller: MockSectionController()) diff --git a/SectionKit/Tests/CollectionViewAdapter/SingleSectionCollectionViewAdapterTests.swift b/SectionKit/Tests/CollectionViewAdapter/SingleSectionCollectionViewAdapterTests.swift index f4308b60..6220c34e 100644 --- a/SectionKit/Tests/CollectionViewAdapter/SingleSectionCollectionViewAdapterTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/SingleSectionCollectionViewAdapterTests.swift @@ -1,11 +1,11 @@ @testable import SectionKit import XCTest -@MainActor -internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { +final class SingleSectionCollectionViewAdapterTests: XCTestCase { // MARK: - Init with datasource - internal func testInitWithDataSourceSetsDataSource() { + @MainActor + func testInitWithDataSourceSetsDataSource() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in nil } let adapter = SingleSectionCollectionViewAdapter( @@ -15,7 +15,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.dataSource === dataSource) } - internal func testInitWithDataSourceSetsViewController() { + @MainActor + func testInitWithDataSourceSetsViewController() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in nil } let viewController = UIViewController() @@ -27,7 +28,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.context.viewController === viewController) } - internal func testInitWithDataSourceSetsScrollViewDelegate() { + @MainActor + func testInitWithDataSourceSetsScrollViewDelegate() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in nil } let scrollViewDelegate = MockScrollViewDelegate() @@ -39,7 +41,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.scrollViewDelegate === scrollViewDelegate) } - internal func testInitWithDataSourceSetsErrorHandler() { + @MainActor + func testInitWithDataSourceSetsErrorHandler() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in nil } let errorHandler = MockErrorHandler() @@ -51,7 +54,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.context.errorHandler is MockErrorHandler) } - internal func testInitWithDataSourceRetrievesInitialSections() { + @MainActor + func testInitWithDataSourceRetrievesInitialSections() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: MockSectionController()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in section } @@ -63,7 +67,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.sections.first === section) } - internal func testInitWithDataSourceSetsContextOnInitialSections() { + @MainActor + func testInitWithDataSourceSetsContextOnInitialSections() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: MockSectionController()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in section } @@ -74,7 +79,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(section.controller.context === adapter.context) } - internal func testInitWithDataSourceSetsCollectionViewDataSourceToSelf() { + @MainActor + func testInitWithDataSourceSetsCollectionViewDataSourceToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in nil } let adapter = SingleSectionCollectionViewAdapter( @@ -84,8 +90,9 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.dataSource === adapter) } + @MainActor @available(iOS 10.0, *) - internal func testInitWithDataSourceSetsCollectionViewDataSourcePrefetchingToSelf() { + func testInitWithDataSourceSetsCollectionViewDataSourcePrefetchingToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in nil } let adapter = SingleSectionCollectionViewAdapter( @@ -95,8 +102,9 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.prefetchDataSource === adapter) } + @MainActor @available(iOS 10.0, *) - internal func testInitWithDataSourceEnablesDataSourcePrefetchingOnCollectionView() { + func testInitWithDataSourceEnablesDataSourcePrefetchingOnCollectionView() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in nil } let _ = SingleSectionCollectionViewAdapter( @@ -106,7 +114,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.isPrefetchingEnabled) } - internal func testInitWithDataSourceSetsCollectionViewDelegateToSelf() { + @MainActor + func testInitWithDataSourceSetsCollectionViewDelegateToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in nil } let adapter = SingleSectionCollectionViewAdapter( @@ -116,8 +125,9 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.delegate === adapter) } + @MainActor @available(iOS 11.0, *) - internal func testInitWithDataSourceSetsCollectionViewDragDelegateToSelf() { + func testInitWithDataSourceSetsCollectionViewDragDelegateToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in nil } let adapter = SingleSectionCollectionViewAdapter( @@ -127,8 +137,9 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.dragDelegate === adapter) } + @MainActor @available(iOS 11.0, *) - internal func testInitWithDataSourceSetsCollectionViewDropDelegateToSelf() { + func testInitWithDataSourceSetsCollectionViewDropDelegateToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in nil } let adapter = SingleSectionCollectionViewAdapter( @@ -138,7 +149,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.dropDelegate === adapter) } - internal func testInitWithDataSourceSetsContextAdapterToSelf() { + @MainActor + func testInitWithDataSourceSetsContextAdapterToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let dataSource = MockSingleSectionCollectionViewAdapterDataSource { _ in nil } let adapter = SingleSectionCollectionViewAdapter( @@ -150,7 +162,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { // MARK: - Init with sections - internal func testInitWithSectionsDoesNotSetDataSource() { + @MainActor + func testInitWithSectionsDoesNotSetDataSource() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter( collectionView: collectionView, @@ -159,7 +172,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssertNil(adapter.dataSource) } - internal func testInitWithSectionsSetsViewController() { + @MainActor + func testInitWithSectionsSetsViewController() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let viewController = UIViewController() let adapter = SingleSectionCollectionViewAdapter( @@ -170,7 +184,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.context.viewController === viewController) } - internal func testInitWithSectionsSetsScrollViewDelegate() { + @MainActor + func testInitWithSectionsSetsScrollViewDelegate() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let scrollViewDelegate = MockScrollViewDelegate() let adapter = SingleSectionCollectionViewAdapter( @@ -181,7 +196,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.scrollViewDelegate === scrollViewDelegate) } - internal func testInitWithSectionsSetsErrorHandler() { + @MainActor + func testInitWithSectionsSetsErrorHandler() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let errorHandler = MockErrorHandler() let adapter = SingleSectionCollectionViewAdapter( @@ -192,7 +208,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.context.errorHandler is MockErrorHandler) } - internal func testInitWithSectionsSetsInitialSections() { + @MainActor + func testInitWithSectionsSetsInitialSections() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: MockSectionController()) let adapter = SingleSectionCollectionViewAdapter( @@ -203,7 +220,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.sections.first === section) } - internal func testInitWithSectionsSetsContextOnInitialSections() { + @MainActor + func testInitWithSectionsSetsContextOnInitialSections() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: MockSectionController()) let adapter = SingleSectionCollectionViewAdapter( @@ -213,7 +231,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(section.controller.context === adapter.context) } - internal func testInitWithSectionsSetsCollectionViewDataSourceToSelf() { + @MainActor + func testInitWithSectionsSetsCollectionViewDataSourceToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter( collectionView: collectionView, @@ -222,8 +241,9 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.dataSource === adapter) } + @MainActor @available(iOS 10.0, *) - internal func testInitWithSectionsSetsCollectionViewDataSourcePrefetchingToSelf() { + func testInitWithSectionsSetsCollectionViewDataSourcePrefetchingToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter( collectionView: collectionView, @@ -232,8 +252,9 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.prefetchDataSource === adapter) } + @MainActor @available(iOS 10.0, *) - internal func testInitWithSectionsEnablesDataSourcePrefetchingOnCollectionView() { + func testInitWithSectionsEnablesDataSourcePrefetchingOnCollectionView() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let _ = SingleSectionCollectionViewAdapter( collectionView: collectionView, @@ -242,7 +263,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.isPrefetchingEnabled) } - internal func testInitWithSectionsSetsCollectionViewDelegateToSelf() { + @MainActor + func testInitWithSectionsSetsCollectionViewDelegateToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter( collectionView: collectionView, @@ -251,8 +273,9 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.delegate === adapter) } + @MainActor @available(iOS 11.0, *) - internal func testInitWithSectionsSetsCollectionViewDragDelegateToSelf() { + func testInitWithSectionsSetsCollectionViewDragDelegateToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter( collectionView: collectionView, @@ -261,8 +284,9 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.dragDelegate === adapter) } + @MainActor @available(iOS 11.0, *) - internal func testInitWithSectionsSetsCollectionViewDropDelegateToSelf() { + func testInitWithSectionsSetsCollectionViewDropDelegateToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter( collectionView: collectionView, @@ -271,7 +295,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(collectionView.dropDelegate === adapter) } - internal func testInitWithSectionsSetsContextAdapterToSelf() { + @MainActor + func testInitWithSectionsSetsContextAdapterToSelf() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter( collectionView: collectionView, @@ -282,7 +307,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { // MARK: - Weak references - internal func testDataSourceIsWeakReferenced() { + @MainActor + func testDataSourceIsWeakReferenced() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter( collectionView: collectionView, @@ -291,7 +317,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssertNil(adapter.dataSource) } - internal func testViewControllerIsWeakReferenced() { + @MainActor + func testViewControllerIsWeakReferenced() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter( collectionView: collectionView, @@ -300,7 +327,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssertNil(adapter.context.viewController) } - internal func testScrollViewDelegateIsWeakReferenced() { + @MainActor + func testScrollViewDelegateIsWeakReferenced() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter( collectionView: collectionView, @@ -311,7 +339,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { // MARK: - Setting CollectionViewSections - internal func testSetCollectionViewSectionsUpdatesContextOnSectionController() { + @MainActor + func testSetCollectionViewSectionsUpdatesContextOnSectionController() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let initialSection = Section(id: "", model: "", controller: MockSectionController()) let adapter = SingleSectionCollectionViewAdapter( @@ -324,7 +353,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(newSection.controller.context === adapter.context) } - internal func testSettingTheDataSourceRetrievesTheSection() { + @MainActor + func testSettingTheDataSourceRetrievesTheSection() { let testExpectation = expectation(description: "Should invoke dataSource") let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: MockSectionController()) @@ -339,7 +369,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testUpdatingTheSectionsReusesSectionControllersWithTheSameId() { + @MainActor + func testUpdatingTheSectionsReusesSectionControllersWithTheSameId() { let testExpectation = expectation(description: "Should invoke didUpdate on the first SectionController") let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let firstSection = Section(id: "section", model: "1", controller: { @@ -364,7 +395,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testUpdatingTheSectionsCalculatesAnUpdate() { + @MainActor + func testUpdatingTheSectionsCalculatesAnUpdate() { let testExpectation = expectation(description: "Should invoke calculateUpdate on the adapter") let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let firstSection = Section(id: "section", model: "1", controller: { @@ -405,7 +437,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testCallingInvalidateDataSourceRetrievesTheSection() { + @MainActor + func testCallingInvalidateDataSourceRetrievesTheSection() { let testExpectation = expectation(description: "Should invoke dataSource") testExpectation.expectedFulfillmentCount = 2 let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) @@ -426,7 +459,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testResettingDataSourceDoesNotRetrieveTheSectionAgain() { + @MainActor + func testResettingDataSourceDoesNotRetrieveTheSectionAgain() { let testExpectation = expectation(description: "Should invoke dataSource") let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: { @@ -446,7 +480,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testSectionsWhenThereIsASection() { + @MainActor + func testSectionsWhenThereIsASection() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let section = Section(id: "", model: "", controller: MockSectionController()) let adapter = SingleSectionCollectionViewAdapter( @@ -457,7 +492,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(adapter.sections.first === section) } - internal func testSectionsWhenThereIsNoSection() { + @MainActor + func testSectionsWhenThereIsNoSection() { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter( collectionView: collectionView, @@ -468,7 +504,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { // MARK: - calculateUpdate - internal func testCalculateUpdateFromSomeToSomeWithTheSameId() throws { + @MainActor + func testCalculateUpdateFromSomeToSomeWithTheSameId() throws { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter(collectionView: collectionView) let update = try XCTUnwrap( @@ -486,7 +523,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssertFalse(update.shouldReload(batchOperation)) } - internal func testCalculateUpdateFromSomeToSomeWithADifferentId() throws { + @MainActor + func testCalculateUpdateFromSomeToSomeWithADifferentId() throws { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter(collectionView: collectionView) let update = try XCTUnwrap( @@ -504,7 +542,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssertFalse(update.shouldReload(batchOperation)) } - internal func testCalculateUpdateFromNoneToSome() throws { + @MainActor + func testCalculateUpdateFromNoneToSome() throws { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter(collectionView: collectionView) let update = try XCTUnwrap( @@ -522,7 +561,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssertFalse(update.shouldReload(batchOperation)) } - internal func testCalculateUpdateFromSomeToNone() throws { + @MainActor + func testCalculateUpdateFromSomeToNone() throws { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter(collectionView: collectionView) let update = try XCTUnwrap( @@ -540,7 +580,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssertFalse(update.shouldReload(batchOperation)) } - internal func testCalculateUpdateFromNoneToNone() throws { + @MainActor + func testCalculateUpdateFromNoneToNone() throws { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter(collectionView: collectionView) let update = try XCTUnwrap(adapter.calculateUpdate(from: nil, to: nil)) @@ -553,7 +594,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssertFalse(update.shouldReload(batchOperation)) } - internal func testCalculateUpdateHasCorrectData() throws { + @MainActor + func testCalculateUpdateHasCorrectData() throws { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter(collectionView: collectionView) let section = Section(id: "1", model: "", controller: MockSectionController()) @@ -568,7 +610,8 @@ internal final class SingleSectionCollectionViewAdapterTests: XCTestCase { XCTAssert(batchOperation.data === section) } - internal func testCalculateUpdateSetDataSetsCollectionViewSection() throws { + @MainActor + func testCalculateUpdateSetDataSetsCollectionViewSection() throws { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let adapter = SingleSectionCollectionViewAdapter(collectionView: collectionView) let section = Section(id: "1", model: "", controller: MockSectionController()) diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSource/BaseCollectionViewAdapterUICollectionViewDataSourceTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSource/BaseCollectionViewAdapterUICollectionViewDataSourceTests.swift index 43213c35..c13c7739 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSource/BaseCollectionViewAdapterUICollectionViewDataSourceTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSource/BaseCollectionViewAdapterUICollectionViewDataSourceTests.swift @@ -2,27 +2,27 @@ import UIKit import XCTest -@MainActor -internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestCase { +class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { + func skipIfNeeded() throws { guard Self.self === BaseCollectionViewAdapterUICollectionViewDataSourceTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createCollectionView( + func createCollectionView( frame: CGRect = .zero, collectionViewLayout layout: UICollectionViewLayout? = nil ) -> UICollectionView { UICollectionView(frame: frame, collectionViewLayout: layout ?? UICollectionViewFlowLayout()) } - internal func createCollectionViewAdapter( + @MainActor + func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, @@ -32,7 +32,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC throw XCTSkip("Tests from base class are skipped") } - internal func testNumberOfSections() throws { + @MainActor + func testNumberOfSections() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, @@ -43,7 +44,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC XCTAssertEqual(adapter.numberOfSections?(in: collectionView), 1) } - internal func testNumberOfItemsInSection() throws { + @MainActor + func testNumberOfItemsInSection() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, @@ -62,7 +64,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC XCTAssertEqual(adapter.collectionView(collectionView, numberOfItemsInSection: 0), 1) } - internal func testNumberOfItemsInSectionWithInvalidIndex() throws { + @MainActor + func testNumberOfItemsInSectionWithInvalidIndex() throws { let testExpectation = expectation(description: "Should invoke errorHandler") let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( @@ -91,7 +94,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC waitForExpectations(timeout: 1) } - internal func testCellForItem() throws { + @MainActor + func testCellForItem() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, @@ -118,7 +122,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC ) } - internal func testCellForItemWithInvalidSectionIndex() throws { + @MainActor + func testCellForItemWithInvalidSectionIndex() throws { let testExpectation = expectation(description: "Should invoke errorHandler") let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( @@ -155,7 +160,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC waitForExpectations(timeout: 1) } - internal func testCellForItemWithInvalidIndexPath() throws { + @MainActor + func testCellForItemWithInvalidIndexPath() throws { let testExpectation = expectation(description: "Should invoke errorHandler") let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( @@ -192,7 +198,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC waitForExpectations(timeout: 1) } - internal func testViewForSupplementaryElementOfKindHeader() throws { + @MainActor + func testViewForSupplementaryElementOfKindHeader() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, @@ -219,7 +226,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC ) } - internal func testViewForSupplementaryElementOfKindWithInvalidSectionIndex() throws { + @MainActor + func testViewForSupplementaryElementOfKindWithInvalidSectionIndex() throws { let testExpectation = expectation(description: "Should invoke errorHandler") let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( @@ -256,7 +264,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC waitForExpectations(timeout: 1) } - internal func testViewForSupplementaryElementOfKindWithInvalidIndexPath() throws { + @MainActor + func testViewForSupplementaryElementOfKindWithInvalidIndexPath() throws { let testExpectation = expectation(description: "Should invoke errorHandler") let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( @@ -293,7 +302,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC waitForExpectations(timeout: 1) } - internal func testViewForSupplementaryElementOfKindFooter() throws { + @MainActor + func testViewForSupplementaryElementOfKindFooter() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, @@ -320,7 +330,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC ) } - internal func testViewForSupplementaryElementOfKindWithUnsupportedElementKind() throws { + @MainActor + func testViewForSupplementaryElementOfKindWithUnsupportedElementKind() throws { let testExpectation = expectation(description: "Should invoke errorHandler") let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( @@ -357,7 +368,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC waitForExpectations(timeout: 1) } - internal func testCanMoveItemAt() throws { + @MainActor + func testCanMoveItemAt() throws { let testExpectation = expectation(description: "Should invoke datasource") let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( @@ -381,7 +393,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC waitForExpectations(timeout: 1) } - internal func testMoveItemInSameSectionCallsDataSource() throws { + @MainActor + func testMoveItemInSameSectionCallsDataSource() throws { let testExpectation = expectation(description: "Should invoke datasource") let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( @@ -408,7 +421,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC waitForExpectations(timeout: 1) } - internal func testMoveItemInDifferentSectionNotCallsDataSource() throws { + @MainActor + func testMoveItemInDifferentSectionNotCallsDataSource() throws { let dataSourceExpectation = expectation(description: "Should not invoke datasource") dataSourceExpectation.fulfill() let errorExpectation = expectation(description: "Should invoke errorHandler") @@ -448,7 +462,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC waitForExpectations(timeout: 1) } - internal func testMoveItemWithInvalidSourceIndexPath() throws { + @MainActor + func testMoveItemWithInvalidSourceIndexPath() throws { let testExpectation = expectation(description: "Should invoke errorHandler") let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( @@ -470,7 +485,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC waitForExpectations(timeout: 1) } - internal func testMoveItemWithInvalidDestinationIndexPath() throws { + @MainActor + func testMoveItemWithInvalidDestinationIndexPath() throws { let testExpectation = expectation(description: "Should invoke errorHandler") let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( @@ -492,15 +508,17 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourceTests: XCTestC waitForExpectations(timeout: 1) } + @MainActor @available(iOS 14.0, *) - internal func testIndexTitlesIsNil() throws { + func testIndexTitlesIsNil() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter(collectionView: collectionView) XCTAssertNil(adapter.indexTitles?(for: collectionView)) } + @MainActor @available(iOS 14.0, *) - internal func testIndexPathForIndexTitle() throws { + func testIndexPathForIndexTitle() throws { let testExpectation = expectation(description: "Should invoke errorHandler") let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSource/ListCollectionViewAdapterUICollectionViewDataSourceTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSource/ListCollectionViewAdapterUICollectionViewDataSourceTests.swift index 421c30ae..c293fd07 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSource/ListCollectionViewAdapterUICollectionViewDataSourceTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSource/ListCollectionViewAdapterUICollectionViewDataSourceTests.swift @@ -2,9 +2,9 @@ import UIKit import XCTest -@MainActor -internal final class ListCollectionViewAdapterUICollectionViewDataSourceTests: BaseCollectionViewAdapterUICollectionViewDataSourceTests { - override internal func createCollectionViewAdapter( +final class ListCollectionViewAdapterUICollectionViewDataSourceTests: BaseCollectionViewAdapterUICollectionViewDataSourceTests { + @MainActor + override func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSource/SingleSectionCollectionViewAdapterUICollectionViewDataSourceTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSource/SingleSectionCollectionViewAdapterUICollectionViewDataSourceTests.swift index 388bb14a..077b35df 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSource/SingleSectionCollectionViewAdapterUICollectionViewDataSourceTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSource/SingleSectionCollectionViewAdapterUICollectionViewDataSourceTests.swift @@ -2,8 +2,8 @@ import UIKit import XCTest -@MainActor -internal final class SingleSectionCollectionViewAdapterUICollectionViewDataSourceTests: BaseCollectionViewAdapterUICollectionViewDataSourceTests { +final class SingleSectionCollectionViewAdapterUICollectionViewDataSourceTests: BaseCollectionViewAdapterUICollectionViewDataSourceTests { + @MainActor override internal func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSourcePrefetching/BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSourcePrefetching/BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift index 8d390447..c6c44abc 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSourcePrefetching/BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSourcePrefetching/BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift @@ -2,28 +2,28 @@ import UIKit import XCTest -@MainActor @available(iOS 10.0, *) -internal class BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests: XCTestCase { +class BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { + func skipIfNeeded() throws { guard Self.self === BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createCollectionView( + func createCollectionView( frame: CGRect = .zero, collectionViewLayout layout: UICollectionViewLayout? = nil ) -> UICollectionView { UICollectionView(frame: frame, collectionViewLayout: layout ?? UICollectionViewFlowLayout()) } - internal func createCollectionViewAdapter( + @MainActor + func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, @@ -33,7 +33,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTes throw XCTSkip("Tests from base class are skipped") } - internal func testPrefetchItems() throws { + @MainActor + func testPrefetchItems() throws { let testExpectation = expectation(description: "Should invoke datasource prefetching delegate") let collectionView = createCollectionView() let itemsToPrefetch = [IndexPath(item: 0, section: 0), IndexPath(item: 1, section: 0)] @@ -58,7 +59,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTes waitForExpectations(timeout: 1) } - internal func testPrefetchItemsWithInvalidIndices() throws { + @MainActor + func testPrefetchItemsWithInvalidIndices() throws { let testExpectation = expectation(description: "Should invoke datasource prefetching delegate") let collectionView = createCollectionView() let itemsToPrefetch = [IndexPath(item: 0, section: 0), IndexPath(item: 1, section: 0)] @@ -84,7 +86,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTes waitForExpectations(timeout: 1) } - internal func testCancelPrefetchingForItems() throws { + @MainActor + func testCancelPrefetchingForItems() throws { let testExpectation = expectation(description: "Should invoke datasource prefetching delegate") let collectionView = createCollectionView() let itemsToCancel = [IndexPath(item: 0, section: 0), IndexPath(item: 1, section: 0)] @@ -109,7 +112,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTes waitForExpectations(timeout: 1) } - internal func testCancelPrefetchingForItemsWithInvalidIndices() throws { + @MainActor + func testCancelPrefetchingForItemsWithInvalidIndices() throws { let testExpectation = expectation(description: "Should invoke datasource prefetching delegate") let collectionView = createCollectionView() let itemsToCancel = [IndexPath(item: 0, section: 0), IndexPath(item: 1, section: 0)] diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSourcePrefetching/ListCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSourcePrefetching/ListCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift index 3907afb9..e60cb041 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSourcePrefetching/ListCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSourcePrefetching/ListCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift @@ -2,10 +2,10 @@ import UIKit import XCTest -@MainActor @available(iOS 10.0, *) -internal final class ListCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests: BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests { - override internal func createCollectionViewAdapter( +final class ListCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests: BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests { + @MainActor + override func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSourcePrefetching/SingleSectionCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSourcePrefetching/SingleSectionCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift index 4771a11b..5e0af08b 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSourcePrefetching/SingleSectionCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDataSourcePrefetching/SingleSectionCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift @@ -2,10 +2,10 @@ import UIKit import XCTest -@MainActor @available(iOS 10.0, *) -internal final class SingleSectionCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests: BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests { - override internal func createCollectionViewAdapter( +final class SingleSectionCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests: BaseCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests { + @MainActor + override func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegate/BaseCollectionViewAdapterUICollectionViewDelegateTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegate/BaseCollectionViewAdapterUICollectionViewDelegateTests.swift index 5ca88825..612b8407 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegate/BaseCollectionViewAdapterUICollectionViewDelegateTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegate/BaseCollectionViewAdapterUICollectionViewDelegateTests.swift @@ -2,27 +2,27 @@ import UIKit import XCTest -@MainActor -internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCase { +class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { + func skipIfNeeded() throws { guard Self.self === BaseCollectionViewAdapterUICollectionViewDelegateTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createCollectionView( + func createCollectionView( frame: CGRect = .zero, collectionViewLayout layout: UICollectionViewLayout? = nil ) -> UICollectionView { UICollectionView(frame: frame, collectionViewLayout: layout ?? UICollectionViewFlowLayout()) } - internal func createCollectionViewAdapter( + @MainActor + func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, @@ -32,7 +32,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas throw XCTSkip("Tests from base class are skipped") } - internal func testShouldHighlightItem() throws { + @MainActor + func testShouldHighlightItem() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -61,7 +62,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testShouldHighlightItemWithoutDelegate() throws { + @MainActor + func testShouldHighlightItemWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let adapter = try createCollectionViewAdapter( @@ -80,7 +82,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } - internal func testDidHighlightItem() throws { + @MainActor + func testDidHighlightItem() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -105,7 +108,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testDidHighlightItemWithoutDelegate() throws { + @MainActor + func testDidHighlightItemWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let adapter = try createCollectionViewAdapter( @@ -121,7 +125,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas adapter.collectionView?(collectionView, didHighlightItemAt: itemIndexPath.indexInCollectionView) } - internal func testDidUnhighlightItem() throws { + @MainActor + func testDidUnhighlightItem() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -146,7 +151,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testDidUnhighlightItemWithoutDelegate() throws { + @MainActor + func testDidUnhighlightItemWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let adapter = try createCollectionViewAdapter( @@ -162,7 +168,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas adapter.collectionView?(collectionView, didUnhighlightItemAt: itemIndexPath.indexInCollectionView) } - internal func testShouldSelectItem() throws { + @MainActor + func testShouldSelectItem() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -191,7 +198,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testShouldSelectItemWithoutDelegate() throws { + @MainActor + func testShouldSelectItemWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let adapter = try createCollectionViewAdapter( @@ -210,7 +218,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } - internal func testShouldDeselectItem() throws { + @MainActor + func testShouldDeselectItem() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -239,7 +248,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testShouldDeselectItemWithoutDelegate() throws { + @MainActor + func testShouldDeselectItemWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let adapter = try createCollectionViewAdapter( @@ -258,7 +268,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } - internal func testDidSelectItem() throws { + @MainActor + func testDidSelectItem() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -283,7 +294,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testDidSelectItemWithoutDelegate() throws { + @MainActor + func testDidSelectItemWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let adapter = try createCollectionViewAdapter( @@ -299,7 +311,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas adapter.collectionView?(collectionView, didSelectItemAt: itemIndexPath.indexInCollectionView) } - internal func testDidDeselectItem() throws { + @MainActor + func testDidDeselectItem() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -324,7 +337,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testDidDeselectItemWithoutDelegate() throws { + @MainActor + func testDidDeselectItemWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let adapter = try createCollectionViewAdapter( @@ -340,7 +354,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas adapter.collectionView?(collectionView, didDeselectItemAt: itemIndexPath.indexInCollectionView) } - internal func testWillDisplayCell() throws { + @MainActor + func testWillDisplayCell() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -367,7 +382,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testWillDisplayCellWithoutDelegate() throws { + @MainActor + func testWillDisplayCellWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let itemCell = MockCollectionViewCell() @@ -384,7 +400,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas adapter.collectionView?(collectionView, willDisplay: itemCell, forItemAt: itemIndexPath.indexInCollectionView) } - internal func testWillDisplayHeaderView() throws { + @MainActor + func testWillDisplayHeaderView() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -416,7 +433,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testWillDisplayFooterView() throws { + @MainActor + func testWillDisplayFooterView() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -448,7 +466,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testWillDisplaySupplementaryViewWithoutDelegate() throws { + @MainActor + func testWillDisplaySupplementaryViewWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let itemHeaderView = MockCollectionReusableView() @@ -470,7 +489,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } - internal func testWillDisplaySupplementaryViewWithInvalidElementKind() throws { + @MainActor + func testWillDisplaySupplementaryViewWithInvalidElementKind() throws { let delegateExpectation = expectation(description: "Should not invoke delegate") delegateExpectation.fulfill() let errorExpectation = expectation(description: "Should invoke errorHandler") @@ -513,7 +533,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testDidEndDisplayingCell() throws { + @MainActor + func testDidEndDisplayingCell() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -540,7 +561,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testDidEndDisplayingCellWithoutDelegate() throws { + @MainActor + func testDidEndDisplayingCellWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let itemCell = MockCollectionViewCell() @@ -557,7 +579,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas adapter.collectionView?(collectionView, didEndDisplaying: itemCell, forItemAt: itemIndexPath.indexInCollectionView) } - internal func testDidEndDisplayingHeaderView() throws { + @MainActor + func testDidEndDisplayingHeaderView() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -589,7 +612,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testDidEndDisplayingFooterView() throws { + @MainActor + func testDidEndDisplayingFooterView() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -621,7 +645,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testDidEndDisplayingSupplementaryViewWithoutDelegate() throws { + @MainActor + func testDidEndDisplayingSupplementaryViewWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let itemHeaderView = MockCollectionReusableView() @@ -643,7 +668,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } - internal func testDidEndDisplayingSupplementaryWithInvalidElementKind() throws { + @MainActor + func testDidEndDisplayingSupplementaryWithInvalidElementKind() throws { let delegateExpectation = expectation(description: "Should not invoke delegate") delegateExpectation.fulfill() let errorExpectation = expectation(description: "Should invoke errorHandler") @@ -687,8 +713,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas } // availability attribute is needed because of deprecation warning + @MainActor @available(iOS, introduced: 6.0, deprecated: 13.0) - internal func testShouldShowMenuForItem() throws { + func testShouldShowMenuForItem() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -718,8 +745,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas } // availability attribute is needed because of deprecation warning + @MainActor @available(iOS, introduced: 6.0, deprecated: 13.0) - internal func testShouldShowMenuForItemWithoutDelegate() throws { + func testShouldShowMenuForItemWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let adapter = try createCollectionViewAdapter( @@ -739,8 +767,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas } // availability attribute is needed because of deprecation warning + @MainActor @available(iOS, introduced: 6.0, deprecated: 13.0) - internal func testCanPerform() throws { + func testCanPerform() throws { class Mock { @objc func perform() { } @@ -782,8 +811,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas } // availability attribute is needed because of deprecation warning + @MainActor @available(iOS, introduced: 6.0, deprecated: 13.0) - internal func testCanPerformWithoutDelegate() throws { + func testCanPerformWithoutDelegate() throws { class Mock { @objc func perform() { } @@ -813,8 +843,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas } // availability attribute is needed because of deprecation warning + @MainActor @available(iOS, introduced: 6.0, deprecated: 13.0) - internal func testPerform() throws { + func testPerform() throws { class Mock { @objc func perform() { } @@ -852,8 +883,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas } // availability attribute is needed because of deprecation warning + @MainActor @available(iOS, introduced: 6.0, deprecated: 13.0) - internal func testPerformWithoutDelegate() throws { + func testPerformWithoutDelegate() throws { class Mock { @objc func perform() { } @@ -879,7 +911,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } - internal func testTransitionLayoutForOldLayout() throws { + @MainActor + func testTransitionLayoutForOldLayout() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, @@ -900,7 +933,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas XCTAssert(transitionLayout.nextLayout === toLayout) } - internal func testCanFocusItem() throws { + @MainActor + func testCanFocusItem() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -929,7 +963,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } - internal func testCanFocusItemWithoutDelegate() throws { + @MainActor + func testCanFocusItemWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let adapter = try createCollectionViewAdapter( @@ -949,7 +984,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas } // Not possible to instantiate `UICollectionViewFocusUpdateContext` -// internal func testShouldUpdateFocus() throws { +// func testShouldUpdateFocus() throws { // let collectionView = createCollectionView() // let adapter = try createCollectionViewAdapter( // collectionView: collectionView, @@ -964,7 +999,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas // } // Not possible to instantiate `UICollectionViewFocusUpdateContext` -// internal func testDidUpdateFocus() throws { +// func testDidUpdateFocus() throws { // let collectionView = createCollectionView() // let adapter = try createCollectionViewAdapter( // collectionView: collectionView, @@ -979,7 +1014,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas // ) // } - internal func testIndexPathForPreferredFocusedView() throws { + @MainActor + func testIndexPathForPreferredFocusedView() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, @@ -990,7 +1026,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas XCTAssertNil(adapter.indexPathForPreferredFocusedView?(in: collectionView)) } - internal func testTargetIndexPathForMoveFromItem() throws { + @MainActor + func testTargetIndexPathForMoveFromItem() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, @@ -1010,7 +1047,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } - internal func testTargetContentOffsetForProposedContentOffset() throws { + @MainActor + func testTargetContentOffsetForProposedContentOffset() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, @@ -1028,8 +1066,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } + @MainActor @available(iOS 11.0, *) - internal func testShouldSpringLoadItem() throws { + func testShouldSpringLoadItem() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -1064,8 +1103,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } + @MainActor @available(iOS 11.0, *) - internal func testShouldSpringLoadItemWithoutDelegate() throws { + func testShouldSpringLoadItemWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let mockContext = MockSpringLoadedInteractionContext() @@ -1089,8 +1129,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } + @MainActor @available(iOS 13.0, *) - internal func testShouldBeginMultipleSelectionInteraction() throws { + func testShouldBeginMultipleSelectionInteraction() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -1122,8 +1163,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } + @MainActor @available(iOS 13.0, *) - internal func testShouldBeginMultipleSelectionInteractionWithoutDelegate() throws { + func testShouldBeginMultipleSelectionInteractionWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let adapter = try createCollectionViewAdapter( @@ -1145,8 +1187,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } + @MainActor @available(iOS 13.0, *) - internal func testDidBeginMultipleSelectionInteraction() throws { + func testDidBeginMultipleSelectionInteraction() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -1174,8 +1217,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } + @MainActor @available(iOS 13.0, *) - internal func testDidBeginMultipleSelectionInteractionWithoutDelegate() throws { + func testDidBeginMultipleSelectionInteractionWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let adapter = try createCollectionViewAdapter( @@ -1194,8 +1238,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } + @MainActor @available(iOS 13.0, *) - internal func testDidEndMultipleSelectionInteraction() throws { + func testDidEndMultipleSelectionInteraction() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, @@ -1206,8 +1251,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas adapter.collectionViewDidEndMultipleSelectionInteraction?(collectionView) } + @MainActor @available(iOS 13.0, *) - internal func testContextMenuConfigurationForItem() throws { + func testContextMenuConfigurationForItem() throws { let testExpectation = expectation(description: "Should invoke delegate") let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) @@ -1242,8 +1288,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas waitForExpectations(timeout: 1) } + @MainActor @available(iOS 13.0, *) - internal func testContextMenuConfigurationForItemWithoutDelegate() throws { + func testContextMenuConfigurationForItemWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = SectionIndexPath(IndexPath(item: 0, section: 0)) let itemPoint = CGPoint(x: 1, y: 2) @@ -1266,8 +1313,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } + @MainActor @available(iOS 13.0, *) - internal func testPreviewForHighlightingContextMenuWithConfiguration() throws { + func testPreviewForHighlightingContextMenuWithConfiguration() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, @@ -1283,8 +1331,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } + @MainActor @available(iOS 13.0, *) - internal func testPreviewForDismissingContextMenuWithConfiguration() throws { + func testPreviewForDismissingContextMenuWithConfiguration() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, @@ -1300,8 +1349,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateTests: XCTestCas ) } + @MainActor @available(iOS 13.0, *) - internal func testWillPerformPreviewActionForMenu() throws { + func testWillPerformPreviewActionForMenu() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegate/ListCollectionViewAdapterUICollectionViewDelegateTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegate/ListCollectionViewAdapterUICollectionViewDelegateTests.swift index 65df0d45..ce8d315c 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegate/ListCollectionViewAdapterUICollectionViewDelegateTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegate/ListCollectionViewAdapterUICollectionViewDelegateTests.swift @@ -2,8 +2,8 @@ import UIKit import XCTest -@MainActor -internal final class ListCollectionViewAdapterUICollectionViewDelegateTests: BaseCollectionViewAdapterUICollectionViewDelegateTests { +final class ListCollectionViewAdapterUICollectionViewDelegateTests: BaseCollectionViewAdapterUICollectionViewDelegateTests { + @MainActor override internal func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegate/SingleSectionCollectionViewAdapterUICollectionViewDelegateTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegate/SingleSectionCollectionViewAdapterUICollectionViewDelegateTests.swift index e81dd5f6..b02f27af 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegate/SingleSectionCollectionViewAdapterUICollectionViewDelegateTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegate/SingleSectionCollectionViewAdapterUICollectionViewDelegateTests.swift @@ -2,8 +2,8 @@ import UIKit import XCTest -@MainActor -internal final class SingleSectionCollectionViewAdapterUICollectionViewDelegateTests: BaseCollectionViewAdapterUICollectionViewDelegateTests { +final class SingleSectionCollectionViewAdapterUICollectionViewDelegateTests: BaseCollectionViewAdapterUICollectionViewDelegateTests { + @MainActor override internal func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift index 887b5b98..ab29f68c 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift @@ -2,27 +2,27 @@ import UIKit import XCTest -@MainActor -internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: XCTestCase { +class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { + func skipIfNeeded() throws { guard Self.self === BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createCollectionView( + func createCollectionView( frame: CGRect = .zero, collectionViewLayout layout: UICollectionViewLayout? = nil ) -> UICollectionView { UICollectionView(frame: frame, collectionViewLayout: layout ?? UICollectionViewFlowLayout()) } - internal func createCollectionViewAdapter( + @MainActor + func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, @@ -33,8 +33,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: } // MARK: - sizeForItem - - internal func testSizeForItemWithDelegate() throws { + @MainActor + func testSizeForItemWithDelegate() throws { let testExpectation = expectation(description: "Should invoke flow layout delegate") let mockLayout = UICollectionViewFlowLayout() let collectionView = createCollectionView(collectionViewLayout: mockLayout) @@ -45,7 +45,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = { + sectionController.layoutProvider = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._sizeForItem = { indexPath, layout, _ in XCTAssertEqual(indexPath.indexInCollectionView, itemIndexPath) @@ -53,7 +53,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: testExpectation.fulfill() return itemSize } - return flowDelegate + return .flowLayout(flowDelegate) }() return sectionController }) @@ -66,7 +66,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: waitForExpectations(timeout: 1) } - internal func testSizeForItemWithoutDelegateButWithFlowLayout() throws { + @MainActor + func testSizeForItemWithoutDelegateButWithFlowLayout() throws { let itemSize = CGSize(width: 1, height: 2) let layout = UICollectionViewFlowLayout() layout.itemSize = itemSize @@ -77,7 +78,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = nil + sectionController.layoutProvider = .flowLayout(nil) return sectionController }) ] @@ -88,8 +89,9 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: ) } - internal func testSizeForItemWithoutDelegateAndFlowLayout() throws { - let layout = UICollectionViewLayout() + @MainActor + func testSizeForItemWithoutDelegateAndFlowLayout() throws { + let layout = UICollectionViewFlowLayout() let collectionView = createCollectionView(collectionViewLayout: layout) let itemIndexPath = IndexPath(item: 0, section: 0) let adapter = try createCollectionViewAdapter( @@ -97,7 +99,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = nil + sectionController.layoutProvider = .flowLayout(nil) return sectionController }) ] @@ -110,7 +112,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: // MARK: - inset - internal func testInsetWithDelegate() throws { + @MainActor + func testInsetWithDelegate() throws { let testExpectation = expectation(description: "Should invoke flow layout delegate") let mockLayout = UICollectionViewFlowLayout() let collectionView = createCollectionView(collectionViewLayout: mockLayout) @@ -120,14 +123,14 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = { + sectionController.layoutProvider = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._inset = { layout, _ in XCTAssert(layout === mockLayout) testExpectation.fulfill() return sectionInset } - return flowDelegate + return .flowLayout(flowDelegate) }() return sectionController }) @@ -140,7 +143,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: waitForExpectations(timeout: 1) } - internal func testInsetWithoutDelegateButWithFlowLayout() throws { + @MainActor + func testInsetWithoutDelegateButWithFlowLayout() throws { let sectionInset = UIEdgeInsets(top: 1, left: 2, bottom: 4, right: 8) let layout = UICollectionViewFlowLayout() layout.sectionInset = sectionInset @@ -150,7 +154,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = nil + sectionController.layoutProvider = .flowLayout(nil) return sectionController }) ] @@ -161,7 +165,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: ) } - internal func testInsetWithoutDelegateAndFlowLayout() throws { + @MainActor + func testInsetWithoutDelegateAndFlowLayout() throws { let layout = UICollectionViewLayout() let collectionView = createCollectionView(collectionViewLayout: layout) let adapter = try createCollectionViewAdapter( @@ -169,7 +174,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = nil + sectionController.layoutProvider = .flowLayout(nil) return sectionController }) ] @@ -182,7 +187,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: // MARK: - minimumLineSpacing - internal func testMinimumLineSpacingWithDelegate() throws { + @MainActor + func testMinimumLineSpacingWithDelegate() throws { let testExpectation = expectation(description: "Should invoke flow layout delegate") let mockLayout = UICollectionViewFlowLayout() let collectionView = createCollectionView(collectionViewLayout: mockLayout) @@ -192,14 +198,14 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = { + sectionController.layoutProvider = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._minimumLineSpacing = { layout, _ in XCTAssert(layout === mockLayout) testExpectation.fulfill() return lineSpacing } - return flowDelegate + return .flowLayout(flowDelegate) }() return sectionController }) @@ -212,7 +218,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: waitForExpectations(timeout: 1) } - internal func testMinimumLineSpacingWithoutDelegateButWithFlowLayout() throws { + @MainActor + func testMinimumLineSpacingWithoutDelegateButWithFlowLayout() throws { let lineSpacing: CGFloat = 1 let layout = UICollectionViewFlowLayout() layout.minimumLineSpacing = lineSpacing @@ -222,7 +229,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = nil + sectionController.layoutProvider = .flowLayout(nil) return sectionController }) ] @@ -233,7 +240,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: ) } - internal func testMinimumLineSpacingWithoutDelegateAndFlowLayout() throws { + @MainActor + func testMinimumLineSpacingWithoutDelegateAndFlowLayout() throws { let layout = UICollectionViewLayout() let collectionView = createCollectionView(collectionViewLayout: layout) let adapter = try createCollectionViewAdapter( @@ -241,7 +249,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = nil + sectionController.layoutProvider = .flowLayout(nil) return sectionController }) ] @@ -254,7 +262,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: // MARK: - minimumInteritemSpacing - internal func testMinimumInteritemSpacingWithDelegate() throws { + @MainActor + func testMinimumInteritemSpacingWithDelegate() throws { let testExpectation = expectation(description: "Should invoke flow layout delegate") let mockLayout = UICollectionViewFlowLayout() let collectionView = createCollectionView(collectionViewLayout: mockLayout) @@ -264,14 +273,14 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = { + sectionController.layoutProvider = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._minimumInteritemSpacing = { layout, _ in XCTAssert(layout === mockLayout) testExpectation.fulfill() return interitemSpacing } - return flowDelegate + return .flowLayout(flowDelegate) }() return sectionController }) @@ -284,7 +293,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: waitForExpectations(timeout: 1) } - internal func testMinimumInteritemSpacingWithoutDelegateButWithFlowLayout() throws { + @MainActor + func testMinimumInteritemSpacingWithoutDelegateButWithFlowLayout() throws { let interitemSpacing: CGFloat = 1 let layout = UICollectionViewFlowLayout() layout.minimumInteritemSpacing = interitemSpacing @@ -294,7 +304,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = nil + sectionController.layoutProvider = .flowLayout(nil) return sectionController }) ] @@ -305,7 +315,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: ) } - internal func testMinimumInteritemSpacingWithoutDelegateAndFlowLayout() throws { + @MainActor + func testMinimumInteritemSpacingWithoutDelegateAndFlowLayout() throws { let layout = UICollectionViewLayout() let collectionView = createCollectionView(collectionViewLayout: layout) let adapter = try createCollectionViewAdapter( @@ -313,7 +324,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = nil + sectionController.layoutProvider = .flowLayout(nil) return sectionController }) ] @@ -326,7 +337,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: // MARK: - referenceSizeForHeader - internal func testReferenceSizeForHeaderWithDelegate() throws { + @MainActor + func testReferenceSizeForHeaderWithDelegate() throws { let testExpectation = expectation(description: "Should invoke flow layout delegate") let mockLayout = UICollectionViewFlowLayout() let collectionView = createCollectionView(collectionViewLayout: mockLayout) @@ -336,14 +348,14 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = { + sectionController.layoutProvider = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._referenceSizeForHeader = { layout, _ in XCTAssert(layout === mockLayout) testExpectation.fulfill() return headerSize } - return flowDelegate + return .flowLayout(flowDelegate) }() return sectionController }) @@ -356,7 +368,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: waitForExpectations(timeout: 1) } - internal func testReferenceSizeForHeaderWithoutDelegateButWithFlowLayout() throws { + @MainActor + func testReferenceSizeForHeaderWithoutDelegateButWithFlowLayout() throws { let headerSize = CGSize(width: 1, height: 2) let layout = UICollectionViewFlowLayout() layout.headerReferenceSize = headerSize @@ -366,7 +379,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = nil + sectionController.layoutProvider = .flowLayout(nil) return sectionController }) ] @@ -377,7 +390,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: ) } - internal func testReferenceSizeForHeaderWithoutDelegateAndFlowLayout() throws { + @MainActor + func testReferenceSizeForHeaderWithoutDelegateAndFlowLayout() throws { let layout = UICollectionViewLayout() let collectionView = createCollectionView(collectionViewLayout: layout) let adapter = try createCollectionViewAdapter( @@ -385,7 +399,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = nil + sectionController.layoutProvider = .flowLayout(nil) return sectionController }) ] @@ -398,7 +412,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: // MARK: - referenceSizeForFooter - internal func testReferenceSizeForFooterWithDelegate() throws { + @MainActor + func testReferenceSizeForFooterWithDelegate() throws { let testExpectation = expectation(description: "Should invoke flow layout delegate") let mockLayout = UICollectionViewFlowLayout() let collectionView = createCollectionView(collectionViewLayout: mockLayout) @@ -408,14 +423,14 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = { + sectionController.layoutProvider = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._referenceSizeForFooter = { layout, _ in XCTAssert(layout === mockLayout) testExpectation.fulfill() return footerSize } - return flowDelegate + return .flowLayout(flowDelegate) }() return sectionController }) @@ -428,7 +443,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: waitForExpectations(timeout: 1) } - internal func testReferenceSizeForFooterWithoutDelegateButWithFlowLayout() throws { + @MainActor + func testReferenceSizeForFooterWithoutDelegateButWithFlowLayout() throws { let footerSize = CGSize(width: 1, height: 2) let layout = UICollectionViewFlowLayout() layout.footerReferenceSize = footerSize @@ -438,7 +454,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = nil + sectionController.layoutProvider = .flowLayout(nil) return sectionController }) ] @@ -449,7 +465,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: ) } - internal func testReferenceSizeForFooterWithoutDelegateAndFlowLayout() throws { + @MainActor + func testReferenceSizeForFooterWithoutDelegateAndFlowLayout() throws { let layout = UICollectionViewLayout() let collectionView = createCollectionView(collectionViewLayout: layout) let adapter = try createCollectionViewAdapter( @@ -457,7 +474,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: sections: [ Section(id: "", model: "", controller: { let sectionController = MockSectionController() - sectionController.flowDelegate = nil + sectionController.layoutProvider = .flowLayout(nil) return sectionController }) ] diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/ListCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/ListCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift index 7227d369..afc5972c 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/ListCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/ListCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift @@ -2,9 +2,9 @@ import UIKit import XCTest -@MainActor -internal final class ListCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests { - override internal func createCollectionViewAdapter( +final class ListCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests { + @MainActor + override func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/SingleSectionCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/SingleSectionCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift index c8049f1d..9f742de6 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/SingleSectionCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/SingleSectionCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift @@ -2,9 +2,9 @@ import UIKit import XCTest -@MainActor -internal final class SingleSectionCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests { - override internal func createCollectionViewAdapter( +final class SingleSectionCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests { + @MainActor + override func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDragDelegate/BaseCollectionViewAdapterUICollectionViewDragDelegateTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDragDelegate/BaseCollectionViewAdapterUICollectionViewDragDelegateTests.swift index 5206be14..884141c1 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDragDelegate/BaseCollectionViewAdapterUICollectionViewDragDelegateTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDragDelegate/BaseCollectionViewAdapterUICollectionViewDragDelegateTests.swift @@ -2,28 +2,28 @@ import UIKit import XCTest -@MainActor @available(iOS 11.0, *) -internal class BaseCollectionViewAdapterUICollectionViewDragDelegateTests: XCTestCase { +class BaseCollectionViewAdapterUICollectionViewDragDelegateTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { + func skipIfNeeded() throws { guard Self.self === BaseCollectionViewAdapterUICollectionViewDragDelegateTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createCollectionView( + func createCollectionView( frame: CGRect = .zero, collectionViewLayout layout: UICollectionViewLayout? = nil ) -> UICollectionView { UICollectionView(frame: frame, collectionViewLayout: layout ?? UICollectionViewFlowLayout()) } - internal func createCollectionViewAdapter( + @MainActor + func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, @@ -35,7 +35,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDragDelegateTests: XCTes // MARK: - itemsForBeginning - internal func testItemsForBeginningWithDelegate() throws { + @MainActor + func testItemsForBeginningWithDelegate() throws { let testExpectation = expectation(description: "Should invoke drag delegate") let collectionView = createCollectionView() let mockSession = MockDragSession() @@ -70,7 +71,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDragDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testItemsForBeginningWithoutDelegate() throws { + @MainActor + func testItemsForBeginningWithoutDelegate() throws { let collectionView = createCollectionView() let mockSession = MockDragSession() let itemIndexPath = IndexPath(item: 0, section: 0) @@ -93,7 +95,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDragDelegateTests: XCTes // MARK: - itemsForAdding - internal func testItemsForAddingWithDelegate() throws { + @MainActor + func testItemsForAddingWithDelegate() throws { let testExpectation = expectation(description: "Should invoke drag delegate") let collectionView = createCollectionView() let mockSession = MockDragSession() @@ -131,7 +134,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDragDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testItemsForAddingWithoutDelegate() throws { + @MainActor + func testItemsForAddingWithoutDelegate() throws { let collectionView = createCollectionView() let mockSession = MockDragSession() let itemIndexPath = IndexPath(item: 0, section: 0) @@ -159,7 +163,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDragDelegateTests: XCTes // MARK: - dragPreviewParametersForItem - internal func testDragPreviewParametersForItemWithDelegate() throws { + @MainActor + func testDragPreviewParametersForItemWithDelegate() throws { let testExpectation = expectation(description: "Should invoke drag delegate") let collectionView = createCollectionView() let itemIndexPath = IndexPath(item: 0, section: 0) @@ -191,7 +196,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDragDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testDragPreviewParametersForItemWithoutDelegate() throws { + @MainActor + func testDragPreviewParametersForItemWithoutDelegate() throws { let collectionView = createCollectionView() let itemIndexPath = IndexPath(item: 0, section: 0) let adapter = try createCollectionViewAdapter( @@ -214,7 +220,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDragDelegateTests: XCTes // MARK: - dragSessionWillBegin - internal func testDragSessionWillBegin() throws { + @MainActor + func testDragSessionWillBegin() throws { let testExpectation = expectation(description: "Should invoke drag delegate") let collectionView = createCollectionView() let mockSession = MockDragSession() @@ -244,7 +251,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDragDelegateTests: XCTes // MARK: - dragSessionDidEnd - internal func testDragSessionDidEnd() throws { + @MainActor + func testDragSessionDidEnd() throws { let testExpectation = expectation(description: "Should invoke drag delegate") let collectionView = createCollectionView() let mockSession = MockDragSession() @@ -274,7 +282,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDragDelegateTests: XCTes // MARK: - dragSessionAllowsMoveOperation - internal func testDragSessionAllowsMoveOperation() throws { + @MainActor + func testDragSessionAllowsMoveOperation() throws { let collectionView = createCollectionView() let mockSession = MockDragSession() let adapter = try createCollectionViewAdapter( @@ -291,7 +300,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDragDelegateTests: XCTes // MARK: - dragSessionIsRestrictedToDraggingApplication - internal func testDragSessionIsRestrictedToDraggingApplication() throws { + @MainActor + func testDragSessionIsRestrictedToDraggingApplication() throws { let collectionView = createCollectionView() let mockSession = MockDragSession() let adapter = try createCollectionViewAdapter( diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDragDelegate/SingleSectionCollectionViewAdapterUICollectionViewDragDelegateTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDragDelegate/SingleSectionCollectionViewAdapterUICollectionViewDragDelegateTests.swift index c8c152b2..d78751cc 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDragDelegate/SingleSectionCollectionViewAdapterUICollectionViewDragDelegateTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDragDelegate/SingleSectionCollectionViewAdapterUICollectionViewDragDelegateTests.swift @@ -2,10 +2,10 @@ import UIKit import XCTest -@MainActor @available(iOS 11.0, *) -internal final class SingleSectionCollectionViewAdapterUICollectionViewDragDelegateTests: BaseCollectionViewAdapterUICollectionViewDragDelegateTests { - override internal func createCollectionViewAdapter( +final class SingleSectionCollectionViewAdapterUICollectionViewDragDelegateTests: BaseCollectionViewAdapterUICollectionViewDragDelegateTests { + @MainActor + override func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDropDelegate/BaseCollectionViewAdapterUICollectionViewDropDelegateTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDropDelegate/BaseCollectionViewAdapterUICollectionViewDropDelegateTests.swift index 43524efe..1050d07a 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDropDelegate/BaseCollectionViewAdapterUICollectionViewDropDelegateTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDropDelegate/BaseCollectionViewAdapterUICollectionViewDropDelegateTests.swift @@ -2,28 +2,28 @@ import UIKit import XCTest -@MainActor @available(iOS 11.0, *) -internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTestCase { +class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { + func skipIfNeeded() throws { guard Self.self === BaseCollectionViewAdapterUICollectionViewDropDelegateTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createCollectionView( + func createCollectionView( frame: CGRect = .zero, collectionViewLayout layout: UICollectionViewLayout? = nil ) -> UICollectionView { UICollectionView(frame: frame, collectionViewLayout: layout ?? UICollectionViewFlowLayout()) } - internal func createCollectionViewAdapter( + @MainActor + func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, @@ -35,7 +35,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes // MARK: - canHandle - internal func testCanHandleWithDelegate() throws { + @MainActor + func testCanHandleWithDelegate() throws { let testExpectation = expectation(description: "Should invoke drop delegate") let collectionView = createCollectionView() let mockSession = MockDropSession() @@ -64,7 +65,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testCanHandleWithoutDelegate() throws { + @MainActor + func testCanHandleWithoutDelegate() throws { let collectionView = createCollectionView() let mockSession = MockDropSession() let adapter = try createCollectionViewAdapter( @@ -85,7 +87,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes // MARK: - dropSessionDidUpdate - internal func testDropSessionDidUpdateWithDestinationIndexPathAndWithInvalidIndex() throws { + @MainActor + func testDropSessionDidUpdateWithDestinationIndexPathAndWithInvalidIndex() throws { let testExpectation = expectation(description: "Should not invoke drop delegate") testExpectation.fulfill() let collectionView = createCollectionView() @@ -119,7 +122,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testDropSessionDidUpdateWithDestinationIndexPathAndWithDelegate() throws { + @MainActor + func testDropSessionDidUpdateWithDestinationIndexPathAndWithDelegate() throws { let testExpectation = expectation(description: "Should invoke drop delegate") let collectionView = createCollectionView() let mockSession = MockDropSession() @@ -154,7 +158,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testDropSessionDidUpdateWithDestinationIndexPathAndWithoutDelegate() throws { + @MainActor + func testDropSessionDidUpdateWithDestinationIndexPathAndWithoutDelegate() throws { let collectionView = createCollectionView() let mockSession = MockDropSession() let indexPath = IndexPath(item: 0, section: 0) @@ -178,7 +183,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes ) } - internal func testDropSessionDidUpdateWithoutDestinationIndexPathAndWithDelegate() throws { + @MainActor + func testDropSessionDidUpdateWithoutDestinationIndexPathAndWithDelegate() throws { let testExpectation = expectation(description: "Should invoke drop delegate") let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) collectionView._indexPathForItem = { _ in IndexPath(item: 0, section: 0) } @@ -213,7 +219,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testDropSessionDidUpdateWithoutDestinationIndexPathButInvalidLocation() throws { + @MainActor + func testDropSessionDidUpdateWithoutDestinationIndexPathButInvalidLocation() throws { let testExpectation = expectation(description: "Should invoke indexPathForItem") let mockPoint = CGPoint(x: 1, y: 2) let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) @@ -241,7 +248,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testDropSessionDidUpdateWithoutDestinationIndexPathButLocationOfInvalidIndexPath() throws { + @MainActor + func testDropSessionDidUpdateWithoutDestinationIndexPathButLocationOfInvalidIndexPath() throws { let testExpectation = expectation(description: "Should invoke indexPathForItem") let mockPoint = CGPoint(x: 1, y: 2) let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) @@ -269,7 +277,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testDropSessionDidUpdateWithoutDestinationIndexPathAndWithoutDelegate() throws { + @MainActor + func testDropSessionDidUpdateWithoutDestinationIndexPathAndWithoutDelegate() throws { let testExpectation = expectation(description: "Should invoke indexPathForItem") let mockPoint = CGPoint(x: 1, y: 2) let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) @@ -303,7 +312,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes // MARK: - performDrop - internal func testPerformDropWithoutDestinationIndexPath() throws { + @MainActor + func testPerformDropWithoutDestinationIndexPath() throws { let testExpectation = expectation(description: "Should not invoke drop delegate") testExpectation.fulfill() let coordinator = MockCollectionViewDropCoordinator() @@ -329,7 +339,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testPerformDropWithInvalidDestinationIndexPath() throws { + @MainActor + func testPerformDropWithInvalidDestinationIndexPath() throws { let testExpectation = expectation(description: "Should not invoke drop delegate") testExpectation.fulfill() let coordinator = MockCollectionViewDropCoordinator() @@ -355,7 +366,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testPerformDropWithUnknownDestinationIndexPath() throws { + @MainActor + func testPerformDropWithUnknownDestinationIndexPath() throws { let testExpectation = expectation(description: "Should not invoke drop delegate") testExpectation.fulfill() let coordinator = MockCollectionViewDropCoordinator() @@ -381,7 +393,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testPerformDropFromDifferentLocalSection() throws { + @MainActor + func testPerformDropFromDifferentLocalSection() throws { let testExpectation = expectation(description: "Should not invoke drop delegate") testExpectation.fulfill() let coordinator = MockCollectionViewDropCoordinator() @@ -414,7 +427,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testPerformDropFromSameLocalSection() throws { + @MainActor + func testPerformDropFromSameLocalSection() throws { let testExpectation = expectation(description: "Should invoke drop delegate") let coordinator = MockCollectionViewDropCoordinator() coordinator.destinationIndexPath = IndexPath(item: 0, section: 0) @@ -446,7 +460,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testPerformDropFromRemote() throws { + @MainActor + func testPerformDropFromRemote() throws { let testExpectation = expectation(description: "Should invoke drop delegate") let coordinator = MockCollectionViewDropCoordinator() coordinator.destinationIndexPath = IndexPath(item: 0, section: 0) @@ -474,7 +489,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testPerformDropWithoutDelegate() throws { + @MainActor + func testPerformDropWithoutDelegate() throws { let coordinator = MockCollectionViewDropCoordinator() coordinator.destinationIndexPath = IndexPath(item: 0, section: 0) let collectionView = createCollectionView() @@ -493,7 +509,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes // MARK: - dropSessionDidEnter - internal func testDropSessionDidEnter() throws { + @MainActor + func testDropSessionDidEnter() throws { let testExpectation = expectation(description: "Should invoke drop delegate") let mockSession = MockDropSession() let collectionView = createCollectionView() @@ -520,7 +537,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes // MARK: - dropSessionDidExit - internal func testDropSessionDidExit() throws { + @MainActor + func testDropSessionDidExit() throws { let testExpectation = expectation(description: "Should invoke drop delegate") let mockSession = MockDropSession() let collectionView = createCollectionView() @@ -547,7 +565,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes // MARK: - dropSessionDidEnd - internal func testDropSessionDidEnd() throws { + @MainActor + func testDropSessionDidEnd() throws { let testExpectation = expectation(description: "Should invoke drop delegate") let mockSession = MockDropSession() let collectionView = createCollectionView() @@ -574,7 +593,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes // MARK: - dropPreviewParametersForItem - internal func testDropPreviewParametersForItemWithDelegate() throws { + @MainActor + func testDropPreviewParametersForItemWithDelegate() throws { let testExpectation = expectation(description: "Should invoke drop delegate") let itemIndexPath = IndexPath(item: 0, section: 0) let mockPreviewParameters = UIDragPreviewParameters() @@ -606,7 +626,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDropDelegateTests: XCTes waitForExpectations(timeout: 1) } - internal func testDropPreviewParametersForItemWithoutDelegate() throws { + @MainActor + func testDropPreviewParametersForItemWithoutDelegate() throws { let collectionView = createCollectionView() let adapter = try createCollectionViewAdapter( collectionView: collectionView, diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDropDelegate/ListCollectionViewAdapterUICollectionViewDropDelegateTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDropDelegate/ListCollectionViewAdapterUICollectionViewDropDelegateTests.swift index 10875847..d7b9a531 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDropDelegate/ListCollectionViewAdapterUICollectionViewDropDelegateTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDropDelegate/ListCollectionViewAdapterUICollectionViewDropDelegateTests.swift @@ -2,9 +2,9 @@ import UIKit import XCTest -@MainActor @available(iOS 11.0, *) -internal final class ListCollectionViewAdapterUICollectionViewDropDelegateTests: BaseCollectionViewAdapterUICollectionViewDropDelegateTests { +final class ListCollectionViewAdapterUICollectionViewDropDelegateTests: BaseCollectionViewAdapterUICollectionViewDropDelegateTests { + @MainActor override internal func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDropDelegate/SingleSectionCollectionViewAdapterUICollectionViewDropDelegateTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDropDelegate/SingleSectionCollectionViewAdapterUICollectionViewDropDelegateTests.swift index 7b6bf72f..3ec3590e 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDropDelegate/SingleSectionCollectionViewAdapterUICollectionViewDropDelegateTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDropDelegate/SingleSectionCollectionViewAdapterUICollectionViewDropDelegateTests.swift @@ -2,10 +2,10 @@ import UIKit import XCTest -@MainActor @available(iOS 11.0, *) -internal final class SingleSectionCollectionViewAdapterUICollectionViewDropDelegateTests: BaseCollectionViewAdapterUICollectionViewDropDelegateTests { - override internal func createCollectionViewAdapter( +final class SingleSectionCollectionViewAdapterUICollectionViewDropDelegateTests: BaseCollectionViewAdapterUICollectionViewDropDelegateTests { + @MainActor + override func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, diff --git a/SectionKit/Tests/CollectionViewAdapter/UIScrollViewDelegate/BaseCollectionViewAdapterUIScrollViewDelegateTests.swift b/SectionKit/Tests/CollectionViewAdapter/UIScrollViewDelegate/BaseCollectionViewAdapterUIScrollViewDelegateTests.swift index 203e881a..96eff4d0 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UIScrollViewDelegate/BaseCollectionViewAdapterUIScrollViewDelegateTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UIScrollViewDelegate/BaseCollectionViewAdapterUIScrollViewDelegateTests.swift @@ -2,27 +2,27 @@ import UIKit import XCTest -@MainActor -internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { +class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { + func skipIfNeeded() throws { guard Self.self === BaseCollectionViewAdapterUIScrollViewDelegateTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createCollectionView( + func createCollectionView( frame: CGRect = .zero, collectionViewLayout layout: UICollectionViewLayout? = nil ) -> UICollectionView { UICollectionView(frame: frame, collectionViewLayout: layout ?? UICollectionViewFlowLayout()) } - internal func createCollectionViewAdapter( + @MainActor + func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, @@ -32,7 +32,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { throw XCTSkip("Tests from base class are skipped") } - internal func testScrollViewDidScroll() throws { + @MainActor + func testScrollViewDidScroll() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() @@ -48,7 +49,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testScrollViewDidZoom() throws { + @MainActor + func testScrollViewDidZoom() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() @@ -64,7 +66,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testScrollViewWillBeginDragging() throws { + @MainActor + func testScrollViewWillBeginDragging() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() @@ -80,7 +83,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testScrollViewWillEndDragging() throws { + @MainActor + func testScrollViewWillEndDragging() throws { let velocity = CGPoint(x: 1, y: 2) let targetContentOffset = CGPoint(x: 4, y: 8) let testExpectation = expectation(description: "Should invoke scroll delegate") @@ -105,7 +109,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testScrollViewDidEndDragging() throws { + @MainActor + func testScrollViewDidEndDragging() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() @@ -122,7 +127,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testScrollViewWillBeginDecelerating() throws { + @MainActor + func testScrollViewWillBeginDecelerating() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() @@ -138,7 +144,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testScrollViewDidEndDecelerating() throws { + @MainActor + func testScrollViewDidEndDecelerating() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() @@ -154,7 +161,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testScrollViewDidEndScrollingAnimation() throws { + @MainActor + func testScrollViewDidEndScrollingAnimation() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() @@ -170,7 +178,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testViewForZooming() throws { + @MainActor + func testViewForZooming() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() @@ -188,7 +197,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testScrollViewWillBeginZooming() throws { + @MainActor + func testScrollViewWillBeginZooming() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() @@ -206,7 +216,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testScrollViewDidEndZooming() throws { + @MainActor + func testScrollViewDidEndZooming() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() @@ -225,7 +236,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testScrollViewShouldScrollToTop() throws { + @MainActor + func testScrollViewShouldScrollToTop() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() @@ -242,7 +254,8 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testScrollViewDidScrollToTop() throws { + @MainActor + func testScrollViewDidScrollToTop() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() @@ -258,8 +271,9 @@ internal class BaseCollectionViewAdapterUIScrollViewDelegateTests: XCTestCase { waitForExpectations(timeout: 1) } + @MainActor @available(iOS 11.0, *) - internal func testScrollViewDidChangeAdjustedContentInset() throws { + func testScrollViewDidChangeAdjustedContentInset() throws { let testExpectation = expectation(description: "Should invoke scroll delegate") let collectionView = createCollectionView() let scrollViewDelegate = MockScrollViewDelegate() diff --git a/SectionKit/Tests/CollectionViewAdapter/UIScrollViewDelegate/ListCollectionViewAdapterUIScrollViewDelegateTests.swift b/SectionKit/Tests/CollectionViewAdapter/UIScrollViewDelegate/ListCollectionViewAdapterUIScrollViewDelegateTests.swift index 6fce48ab..3ea28e10 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UIScrollViewDelegate/ListCollectionViewAdapterUIScrollViewDelegateTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UIScrollViewDelegate/ListCollectionViewAdapterUIScrollViewDelegateTests.swift @@ -2,9 +2,9 @@ import UIKit import XCTest -@MainActor -internal final class ListCollectionViewAdapterUIScrollViewDelegateTests: BaseCollectionViewAdapterUIScrollViewDelegateTests { - override internal func createCollectionViewAdapter( +final class ListCollectionViewAdapterUIScrollViewDelegateTests: BaseCollectionViewAdapterUIScrollViewDelegateTests { + @MainActor + override func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, diff --git a/SectionKit/Tests/CollectionViewAdapter/UIScrollViewDelegate/SingleSectionCollectionViewAdapterUIScrollViewDelegateTests.swift b/SectionKit/Tests/CollectionViewAdapter/UIScrollViewDelegate/SingleSectionCollectionViewAdapterUIScrollViewDelegateTests.swift index eb321b1f..3790036d 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UIScrollViewDelegate/SingleSectionCollectionViewAdapterUIScrollViewDelegateTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UIScrollViewDelegate/SingleSectionCollectionViewAdapterUIScrollViewDelegateTests.swift @@ -2,9 +2,9 @@ import UIKit import XCTest -@MainActor -internal final class SingleSectionCollectionViewAdapterUIScrollViewDelegateTests: BaseCollectionViewAdapterUIScrollViewDelegateTests { - override internal func createCollectionViewAdapter( +final class SingleSectionCollectionViewAdapterUIScrollViewDelegateTests: BaseCollectionViewAdapterUIScrollViewDelegateTests { + @MainActor + override func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, diff --git a/SectionKit/Tests/SectionController/BaseSectionControllerTests.swift b/SectionKit/Tests/SectionController/BaseSectionControllerTests.swift index 26a3edb7..4e6e3384 100644 --- a/SectionKit/Tests/SectionController/BaseSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/BaseSectionControllerTests.swift @@ -1,47 +1,54 @@ import SectionKit import XCTest -@MainActor -internal final class BaseSectionControllerTests: XCTestCase { - internal func testContextIsNil() { +final class BaseSectionControllerTests: XCTestCase { + @MainActor + func testContextIsNil() { let sectionController = BaseSectionController() XCTAssertNil(sectionController.context) } - internal func testDataSourceIsSelf() { + @MainActor + func testDataSourceIsSelf() { let sectionController = BaseSectionController() XCTAssert(sectionController.dataSource === sectionController) } + @MainActor @available(iOS 10.0, *) - internal func testDataSourcePrefetchingDelegateIsSelf() { + func testDataSourcePrefetchingDelegateIsSelf() { let sectionController = BaseSectionController() XCTAssert(sectionController.dataSourcePrefetchingDelegate === sectionController) } - internal func testDelegateIsSelf() { + @MainActor + func testDelegateIsSelf() { let sectionController = BaseSectionController() XCTAssert(sectionController.delegate === sectionController) } - internal func testFlowDelegateIsSelf() { + @MainActor + func testFlowDelegateIsSelf() { let sectionController = BaseSectionController() XCTAssert(sectionController.flowDelegate === sectionController) } + @MainActor @available(iOS 11.0, *) - internal func testDragDelegateIsSelf() { + func testDragDelegateIsSelf() { let sectionController = BaseSectionController() XCTAssert(sectionController.dragDelegate === sectionController) } + @MainActor @available(iOS 11.0, *) - internal func testDropDelegateIsSelf() { + func testDropDelegateIsSelf() { let sectionController = BaseSectionController() XCTAssert(sectionController.dropDelegate === sectionController) } - internal func testDidUpdateModelDoesNothing() { + @MainActor + func testDidUpdateModelDoesNothing() { let sectionController = BaseSectionController() sectionController.didUpdate(model: "") } diff --git a/SectionKit/Tests/SectionController/ListSectionControllerTests.swift b/SectionKit/Tests/SectionController/ListSectionControllerTests.swift index 4aa22352..be716a84 100644 --- a/SectionKit/Tests/SectionController/ListSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/ListSectionControllerTests.swift @@ -1,15 +1,16 @@ @testable import SectionKit import XCTest -@MainActor -internal final class ListSectionControllerTests: XCTestCase { - internal func testDidUpdateModelWithValidTypeSetsModel() { +final class ListSectionControllerTests: XCTestCase { + @MainActor + func testDidUpdateModelWithValidTypeSetsModel() { let sectionController = ListSectionController(model: "1") sectionController.didUpdate(model: "2") XCTAssertEqual(sectionController.model, "2") } - internal func testDidUpdateModelWithInvalidType() { + @MainActor + func testDidUpdateModelWithInvalidType() { let errorExpectation = expectation(description: "The errorHandler should be called") let sectionController = ListSectionController(model: "1") let context = MainCollectionViewContext( @@ -32,7 +33,8 @@ internal final class ListSectionControllerTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testInitDoesNotUpdateItemsIfShouldNotUpdateItems() { + @MainActor + func testInitDoesNotUpdateItemsIfShouldNotUpdateItems() { class TestSectionController: ListSectionController { var itemsForModelExpectation: XCTestExpectation? @@ -56,7 +58,8 @@ internal final class ListSectionControllerTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testSettingModelDoesNotUpdateItemsIfShouldNotUpdateItems() { + @MainActor + func testSettingModelDoesNotUpdateItemsIfShouldNotUpdateItems() { class TestSectionController: ListSectionController { var itemsForModelExpectation: XCTestExpectation? @@ -83,12 +86,14 @@ internal final class ListSectionControllerTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testShouldUpdateItemsDefaultsToTrue() { + @MainActor + func testShouldUpdateItemsDefaultsToTrue() { let sectionController = ListSectionController(model: "1") XCTAssert(sectionController.shouldUpdateItems(afterModelChangedTo: "2")) } - internal func testItemsForModelInvokesNotImplementedError() { + @MainActor + func testItemsForModelInvokesNotImplementedError() { let errorExpectation = expectation(description: "The errorHandler should be called") let sectionController = ListSectionController(model: "1") let context = MainCollectionViewContext( @@ -108,7 +113,8 @@ internal final class ListSectionControllerTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testNumberOfItems() { + @MainActor + func testNumberOfItems() { let sectionController = ListSectionController(model: "1") sectionController.items = ["1", "2"] let context = MainCollectionViewContext( diff --git a/SectionKit/Tests/SectionController/ProtocolDefaultValuesSectionControllerTests.swift b/SectionKit/Tests/SectionController/ProtocolDefaultValuesSectionControllerTests.swift index a63371e8..dde22eac 100644 --- a/SectionKit/Tests/SectionController/ProtocolDefaultValuesSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/ProtocolDefaultValuesSectionControllerTests.swift @@ -1,42 +1,46 @@ import SectionKit import XCTest -@MainActor -internal final class ProtocolDefaultValuesSectionControllerTests: XCTestCase { - private func createSectionController() -> SectionController { +final class ProtocolDefaultValuesSectionControllerTests: XCTestCase { + private var sut: SectionController! + + @MainActor + override func setUp() { + super.setUp() class DefaultSectionController: SectionController { var context: CollectionViewContext? - var dataSource: SectionDataSource = MockSectionDataSource() + let dataSource: SectionDataSource = MockSectionDataSource() + let layoutProvider: SectionLayoutProvider = .flowLayout(nil) func didUpdate(model: Any) { } } - return DefaultSectionController() + sut = DefaultSectionController() } - @available(iOS 10.0, *) - internal func testDataSourcePrefetchingDelegateIsNil() { - let sectionController = createSectionController() - XCTAssertNil(sectionController.dataSourcePrefetchingDelegate) + override func tearDown() { + sut = nil + super.tearDown() } - internal func testDelegateIsNil() { - let sectionController = createSectionController() - XCTAssertNil(sectionController.delegate) + @MainActor + @available(iOS 10.0, *) + func testDataSourcePrefetchingDelegateIsNil() { + XCTAssertNil(sut.dataSourcePrefetchingDelegate) } - internal func testFlowDelegateIsNil() { - let sectionController = createSectionController() - XCTAssertNil(sectionController.flowDelegate) + @MainActor + func testDelegateIsNil() { + XCTAssertNil(sut.delegate) } + @MainActor @available(iOS 11.0, *) - internal func testDragDelegateIsNil() { - let sectionController = createSectionController() - XCTAssertNil(sectionController.dragDelegate) + func testDragDelegateIsNil() { + XCTAssertNil(sut.dragDelegate) } + @MainActor @available(iOS 11.0, *) - internal func testDropDelegateIsNil() { - let sectionController = createSectionController() - XCTAssertNil(sectionController.dropDelegate) + func testDropDelegateIsNil() { + XCTAssertNil(sut.dropDelegate) } } diff --git a/SectionKit/Tests/SectionController/SectionDataSource/BaseSectionControllerSectionDataSourceTests.swift b/SectionKit/Tests/SectionController/SectionDataSource/BaseSectionControllerSectionDataSourceTests.swift index ec0b8ca3..39630800 100644 --- a/SectionKit/Tests/SectionController/SectionDataSource/BaseSectionControllerSectionDataSourceTests.swift +++ b/SectionKit/Tests/SectionController/SectionDataSource/BaseSectionControllerSectionDataSourceTests.swift @@ -1,8 +1,8 @@ import SectionKit import XCTest -@MainActor -internal final class BaseSectionControllerSectionDataSourceTests: BaseSectionDataSourceTests { +final class BaseSectionControllerSectionDataSourceTests: BaseSectionDataSourceTests { + @MainActor override func createSectionDataSource() throws -> SectionDataSource { BaseSectionController() } diff --git a/SectionKit/Tests/SectionController/SectionDataSource/BaseSectionDataSourceTests.swift b/SectionKit/Tests/SectionController/SectionDataSource/BaseSectionDataSourceTests.swift index a27e3c49..721334c8 100644 --- a/SectionKit/Tests/SectionController/SectionDataSource/BaseSectionDataSourceTests.swift +++ b/SectionKit/Tests/SectionController/SectionDataSource/BaseSectionDataSourceTests.swift @@ -1,24 +1,25 @@ import SectionKit import XCTest -@MainActor -internal class BaseSectionDataSourceTests: XCTestCase { +class BaseSectionDataSourceTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { + func skipIfNeeded() throws { guard Self.self === BaseSectionDataSourceTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createSectionDataSource() throws -> SectionDataSource { + @MainActor + func createSectionDataSource() throws -> SectionDataSource { throw XCTSkip("Tests from base class are skipped") } - internal func testNumberOfItems() throws { + @MainActor + func testNumberOfItems() throws { let sectionDataSource = try createSectionDataSource() let context = MainCollectionViewContext( viewController: nil, @@ -28,7 +29,8 @@ internal class BaseSectionDataSourceTests: XCTestCase { XCTAssertEqual(sectionDataSource.numberOfItems(in: context), 0) } - internal func testCellForItem() throws { + @MainActor + func testCellForItem() throws { let errorExpectation = expectation(description: "The errorHandler should be called") let sectionDataSource = try createSectionDataSource() let context = MainCollectionViewContext( @@ -54,7 +56,8 @@ internal class BaseSectionDataSourceTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testHeaderView() throws { + @MainActor + func testHeaderView() throws { let errorExpectation = expectation(description: "The errorHandler should be called") let sectionDataSource = try createSectionDataSource() let context = MainCollectionViewContext( @@ -80,7 +83,8 @@ internal class BaseSectionDataSourceTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testFooterView() throws { + @MainActor + func testFooterView() throws { let errorExpectation = expectation(description: "The errorHandler should be called") let sectionDataSource = try createSectionDataSource() let context = MainCollectionViewContext( @@ -106,7 +110,8 @@ internal class BaseSectionDataSourceTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testCanMoveItem() throws { + @MainActor + func testCanMoveItem() throws { let sectionDataSource = try createSectionDataSource() let context = MainCollectionViewContext( viewController: nil, @@ -117,7 +122,8 @@ internal class BaseSectionDataSourceTests: XCTestCase { XCTAssertFalse(sectionDataSource.canMoveItem(at: indexPath, in: context)) } - internal func testMoveItem() throws { + @MainActor + func testMoveItem() throws { let sectionDataSource = try createSectionDataSource() let context = MainCollectionViewContext( viewController: nil, diff --git a/SectionKit/Tests/SectionController/SectionDataSource/ProtocolDefaultValuesSectionDataSourceTests.swift b/SectionKit/Tests/SectionController/SectionDataSource/ProtocolDefaultValuesSectionDataSourceTests.swift index 26439d23..ea2450b3 100644 --- a/SectionKit/Tests/SectionController/SectionDataSource/ProtocolDefaultValuesSectionDataSourceTests.swift +++ b/SectionKit/Tests/SectionController/SectionDataSource/ProtocolDefaultValuesSectionDataSourceTests.swift @@ -1,8 +1,8 @@ import SectionKit import XCTest -@MainActor -internal final class ProtocolDefaultValuesSectionDataSourceTests: BaseSectionDataSourceTests { +final class ProtocolDefaultValuesSectionDataSourceTests: BaseSectionDataSourceTests { + @MainActor override func createSectionDataSource() throws -> SectionDataSource { class DefaultSectionDataSource: SectionDataSource { func numberOfItems(in context: CollectionViewContext) -> Int { diff --git a/SectionKit/Tests/SectionController/SectionDataSourcePrefetchingDelegate/BaseSectionControllerSectionDataSourcePrefetchingDelegateTests.swift b/SectionKit/Tests/SectionController/SectionDataSourcePrefetchingDelegate/BaseSectionControllerSectionDataSourcePrefetchingDelegateTests.swift index 84096c71..f7ca5f05 100644 --- a/SectionKit/Tests/SectionController/SectionDataSourcePrefetchingDelegate/BaseSectionControllerSectionDataSourcePrefetchingDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionDataSourcePrefetchingDelegate/BaseSectionControllerSectionDataSourcePrefetchingDelegateTests.swift @@ -1,9 +1,9 @@ import SectionKit import XCTest -@MainActor @available(iOS 10.0, *) -internal final class BaseSectionControllerSectionDataSourcePrefetchingDelegateTests: BaseSectionDataSourcePrefetchingDelegateTests { +final class BaseSectionControllerSectionDataSourcePrefetchingDelegateTests: BaseSectionDataSourcePrefetchingDelegateTests { + @MainActor override func createSectionDataSourcePrefetchingDelegate() throws -> SectionDataSourcePrefetchingDelegate { BaseSectionController() } diff --git a/SectionKit/Tests/SectionController/SectionDataSourcePrefetchingDelegate/BaseSectionDataSourcePrefetchingDelegateTests.swift b/SectionKit/Tests/SectionController/SectionDataSourcePrefetchingDelegate/BaseSectionDataSourcePrefetchingDelegateTests.swift index 52db69de..d33993e1 100644 --- a/SectionKit/Tests/SectionController/SectionDataSourcePrefetchingDelegate/BaseSectionDataSourcePrefetchingDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionDataSourcePrefetchingDelegate/BaseSectionDataSourcePrefetchingDelegateTests.swift @@ -1,25 +1,26 @@ import SectionKit import XCTest -@MainActor @available(iOS 10.0, *) -internal class BaseSectionDataSourcePrefetchingDelegateTests: XCTestCase { +class BaseSectionDataSourcePrefetchingDelegateTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { + func skipIfNeeded() throws { guard Self.self === BaseSectionDataSourcePrefetchingDelegateTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createSectionDataSourcePrefetchingDelegate() throws -> SectionDataSourcePrefetchingDelegate { + @MainActor + func createSectionDataSourcePrefetchingDelegate() throws -> SectionDataSourcePrefetchingDelegate { throw XCTSkip("Tests from base class are skipped") } - internal func testPrefetchItems() throws { + @MainActor + func testPrefetchItems() throws { let sectionDataSourcePrefetchingDelegate = try createSectionDataSourcePrefetchingDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -29,7 +30,8 @@ internal class BaseSectionDataSourcePrefetchingDelegateTests: XCTestCase { sectionDataSourcePrefetchingDelegate.prefetchItems(at: [], in: context) } - internal func testCancelPrefetchingForItems() throws { + @MainActor + func testCancelPrefetchingForItems() throws { let sectionDataSourcePrefetchingDelegate = try createSectionDataSourcePrefetchingDelegate() let context = MainCollectionViewContext( viewController: nil, diff --git a/SectionKit/Tests/SectionController/SectionDataSourcePrefetchingDelegate/ProtocolDefaultValuesSectionDataSourcePrefetchingDelegateTests.swift b/SectionKit/Tests/SectionController/SectionDataSourcePrefetchingDelegate/ProtocolDefaultValuesSectionDataSourcePrefetchingDelegateTests.swift index 2a7e2c49..25d2d4fc 100644 --- a/SectionKit/Tests/SectionController/SectionDataSourcePrefetchingDelegate/ProtocolDefaultValuesSectionDataSourcePrefetchingDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionDataSourcePrefetchingDelegate/ProtocolDefaultValuesSectionDataSourcePrefetchingDelegateTests.swift @@ -1,9 +1,9 @@ import SectionKit import XCTest -@MainActor @available(iOS 10.0, *) -internal final class ProtocolDefaultValuesSectionDataSourcePrefetchingDelegateTests: BaseSectionDataSourcePrefetchingDelegateTests { +final class ProtocolDefaultValuesSectionDataSourcePrefetchingDelegateTests: BaseSectionDataSourcePrefetchingDelegateTests { + @MainActor override func createSectionDataSourcePrefetchingDelegate() throws -> SectionDataSourcePrefetchingDelegate { class DefaultSectionDataSourcePrefetchingDelegate: SectionDataSourcePrefetchingDelegate { func prefetchItems(at indexPaths: [SectionIndexPath], in context: CollectionViewContext) { } diff --git a/SectionKit/Tests/SectionController/SectionDelegate/BaseSectionControllerSectionDelegateTests.swift b/SectionKit/Tests/SectionController/SectionDelegate/BaseSectionControllerSectionDelegateTests.swift index fa3e5011..4a865224 100644 --- a/SectionKit/Tests/SectionController/SectionDelegate/BaseSectionControllerSectionDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionDelegate/BaseSectionControllerSectionDelegateTests.swift @@ -1,8 +1,8 @@ import SectionKit import XCTest -@MainActor -internal final class BaseSectionControllerSectionDelegateTests: BaseSectionDelegateTests { +final class BaseSectionControllerSectionDelegateTests: BaseSectionDelegateTests { + @MainActor override func createSectionDelegate() throws -> SectionDelegate { BaseSectionController() } diff --git a/SectionKit/Tests/SectionController/SectionDelegate/BaseSectionDelegateTests.swift b/SectionKit/Tests/SectionController/SectionDelegate/BaseSectionDelegateTests.swift index db4a12c6..8a8f06e8 100644 --- a/SectionKit/Tests/SectionController/SectionDelegate/BaseSectionDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionDelegate/BaseSectionDelegateTests.swift @@ -1,24 +1,25 @@ import SectionKit import XCTest -@MainActor -internal class BaseSectionDelegateTests: XCTestCase { +class BaseSectionDelegateTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { + func skipIfNeeded() throws { guard Self.self === BaseSectionDelegateTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createSectionDelegate() throws -> SectionDelegate { + @MainActor + func createSectionDelegate() throws -> SectionDelegate { throw XCTSkip("Tests from base class are skipped") } - internal func testShouldHighlightItem() throws { + @MainActor + func testShouldHighlightItem() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -29,7 +30,8 @@ internal class BaseSectionDelegateTests: XCTestCase { XCTAssert(sectionDelegate.shouldHighlightItem(at: indexPath, in: context)) } - internal func testDidHighlightItem() throws { + @MainActor + func testDidHighlightItem() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -40,7 +42,8 @@ internal class BaseSectionDelegateTests: XCTestCase { sectionDelegate.didHighlightItem(at: indexPath, in: context) } - internal func testDidUnhighlightItem() throws { + @MainActor + func testDidUnhighlightItem() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -51,7 +54,8 @@ internal class BaseSectionDelegateTests: XCTestCase { sectionDelegate.didUnhighlightItem(at: indexPath, in: context) } - internal func testShouldSelectItem() throws { + @MainActor + func testShouldSelectItem() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -62,7 +66,8 @@ internal class BaseSectionDelegateTests: XCTestCase { XCTAssert(sectionDelegate.shouldSelectItem(at: indexPath, in: context)) } - internal func testShouldDeselectItem() throws { + @MainActor + func testShouldDeselectItem() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -73,7 +78,8 @@ internal class BaseSectionDelegateTests: XCTestCase { XCTAssert(sectionDelegate.shouldDeselectItem(at: indexPath, in: context)) } - internal func testDidSelectItem() throws { + @MainActor + func testDidSelectItem() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -84,7 +90,8 @@ internal class BaseSectionDelegateTests: XCTestCase { sectionDelegate.didSelectItem(at: indexPath, in: context) } - internal func testDidDeselectItem() throws { + @MainActor + func testDidDeselectItem() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -95,7 +102,8 @@ internal class BaseSectionDelegateTests: XCTestCase { sectionDelegate.didDeselectItem(at: indexPath, in: context) } - internal func testWillDisplayCell() throws { + @MainActor + func testWillDisplayCell() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -110,7 +118,8 @@ internal class BaseSectionDelegateTests: XCTestCase { ) } - internal func testWillDisplayHeaderView() throws { + @MainActor + func testWillDisplayHeaderView() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -125,7 +134,8 @@ internal class BaseSectionDelegateTests: XCTestCase { ) } - internal func testWillDisplayFooterView() throws { + @MainActor + func testWillDisplayFooterView() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -140,7 +150,8 @@ internal class BaseSectionDelegateTests: XCTestCase { ) } - internal func testDidEndDisplayingCell() throws { + @MainActor + func testDidEndDisplayingCell() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -155,7 +166,8 @@ internal class BaseSectionDelegateTests: XCTestCase { ) } - internal func testDidEndDisplayingHeaderView() throws { + @MainActor + func testDidEndDisplayingHeaderView() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -170,7 +182,8 @@ internal class BaseSectionDelegateTests: XCTestCase { ) } - internal func testDidEndDisplayingFooterView() throws { + @MainActor + func testDidEndDisplayingFooterView() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -186,8 +199,9 @@ internal class BaseSectionDelegateTests: XCTestCase { } // availability attribute is needed because of deprecation warning + @MainActor @available(iOS, introduced: 6.0, deprecated: 13.0) - internal func testShouldShowMenuForItem() throws { + func testShouldShowMenuForItem() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -202,8 +216,9 @@ internal class BaseSectionDelegateTests: XCTestCase { } // availability attribute is needed because of deprecation warning + @MainActor @available(iOS, introduced: 6.0, deprecated: 13.0) - internal func testCanPerform() throws { + func testCanPerform() throws { class Mock { @objc func perform() { } @@ -225,8 +240,9 @@ internal class BaseSectionDelegateTests: XCTestCase { } // availability attribute is needed because of deprecation warning + @MainActor @available(iOS, introduced: 6.0, deprecated: 13.0) - internal func testPerform() throws { + func testPerform() throws { class Mock { @objc func perform() { } @@ -247,7 +263,8 @@ internal class BaseSectionDelegateTests: XCTestCase { ) } - internal func testCanFocusItem() throws { + @MainActor + func testCanFocusItem() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -267,8 +284,9 @@ internal class BaseSectionDelegateTests: XCTestCase { ) } + @MainActor @available(iOS 11.0, *) - internal func testShouldSpringLoadItem() throws { + func testShouldSpringLoadItem() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -284,8 +302,9 @@ internal class BaseSectionDelegateTests: XCTestCase { )) } + @MainActor @available(iOS 13.0, *) - internal func testShouldBeginMultipleSelectionInteraction() throws { + func testShouldBeginMultipleSelectionInteraction() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -299,8 +318,9 @@ internal class BaseSectionDelegateTests: XCTestCase { )) } + @MainActor @available(iOS 13.0, *) - internal func testDidBeginMultipleSelectionInteraction() throws { + func testDidBeginMultipleSelectionInteraction() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -314,8 +334,9 @@ internal class BaseSectionDelegateTests: XCTestCase { ) } + @MainActor @available(iOS 13.0, *) - internal func testContextMenuConfigurationForItem() throws { + func testContextMenuConfigurationForItem() throws { let sectionDelegate = try createSectionDelegate() let context = MainCollectionViewContext( viewController: nil, diff --git a/SectionKit/Tests/SectionController/SectionDelegate/ProtocolDefaultValuesSectionDelegateTests.swift b/SectionKit/Tests/SectionController/SectionDelegate/ProtocolDefaultValuesSectionDelegateTests.swift index cc57ad87..b908b3b1 100644 --- a/SectionKit/Tests/SectionController/SectionDelegate/ProtocolDefaultValuesSectionDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionDelegate/ProtocolDefaultValuesSectionDelegateTests.swift @@ -1,8 +1,8 @@ import SectionKit import XCTest -@MainActor -internal final class ProtocolDefaultValuesSectionDelegateTests: BaseSectionDelegateTests { +final class ProtocolDefaultValuesSectionDelegateTests: BaseSectionDelegateTests { + @MainActor override func createSectionDelegate() throws -> SectionDelegate { class DefaultSectionDelegate: SectionDelegate { } return DefaultSectionDelegate() diff --git a/SectionKit/Tests/SectionController/SectionDragDelegate/BaseSectionControllerSectionDragDelegateTests.swift b/SectionKit/Tests/SectionController/SectionDragDelegate/BaseSectionControllerSectionDragDelegateTests.swift index 05b44795..6d8cb1dc 100644 --- a/SectionKit/Tests/SectionController/SectionDragDelegate/BaseSectionControllerSectionDragDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionDragDelegate/BaseSectionControllerSectionDragDelegateTests.swift @@ -1,9 +1,9 @@ import SectionKit import XCTest -@MainActor @available(iOS 11.0, *) -internal final class BaseSectionControllerSectionDragDelegateTests: BaseSectionDragDelegateTests { +final class BaseSectionControllerSectionDragDelegateTests: BaseSectionDragDelegateTests { + @MainActor override func createSectionDragDelegate() throws -> SectionDragDelegate { BaseSectionController() } diff --git a/SectionKit/Tests/SectionController/SectionDragDelegate/BaseSectionDragDelegateTests.swift b/SectionKit/Tests/SectionController/SectionDragDelegate/BaseSectionDragDelegateTests.swift index 0ca1b261..e0b7d7ab 100644 --- a/SectionKit/Tests/SectionController/SectionDragDelegate/BaseSectionDragDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionDragDelegate/BaseSectionDragDelegateTests.swift @@ -1,25 +1,26 @@ import SectionKit import XCTest -@MainActor @available(iOS 11.0, *) -internal class BaseSectionDragDelegateTests: XCTestCase { +class BaseSectionDragDelegateTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { + func skipIfNeeded() throws { guard Self.self === BaseSectionDragDelegateTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createSectionDragDelegate() throws -> SectionDragDelegate { + @MainActor + func createSectionDragDelegate() throws -> SectionDragDelegate { throw XCTSkip("Tests from base class are skipped") } - internal func testDragItemsForBeginning() throws { + @MainActor + func testDragItemsForBeginning() throws { let sectionDragDelegate = try createSectionDragDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -35,7 +36,8 @@ internal class BaseSectionDragDelegateTests: XCTestCase { ).isEmpty) } - internal func testDragItemsForAdding() throws { + @MainActor + func testDragItemsForAdding() throws { let sectionDragDelegate = try createSectionDragDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -52,7 +54,8 @@ internal class BaseSectionDragDelegateTests: XCTestCase { ).isEmpty) } - internal func testDragSessionWillBegin() throws { + @MainActor + func testDragSessionWillBegin() throws { let sectionDragDelegate = try createSectionDragDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -66,7 +69,8 @@ internal class BaseSectionDragDelegateTests: XCTestCase { ) } - internal func testDragSessionDidEnd() throws { + @MainActor + func testDragSessionDidEnd() throws { let sectionDragDelegate = try createSectionDragDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -80,7 +84,8 @@ internal class BaseSectionDragDelegateTests: XCTestCase { ) } - internal func testDragPreviewParametersForItem() throws { + @MainActor + func testDragPreviewParametersForItem() throws { let sectionDragDelegate = try createSectionDragDelegate() let context = MainCollectionViewContext( viewController: nil, diff --git a/SectionKit/Tests/SectionController/SectionDragDelegate/ProtocolDefaultValuesSectionDragDelegateTests.swift b/SectionKit/Tests/SectionController/SectionDragDelegate/ProtocolDefaultValuesSectionDragDelegateTests.swift index c5b2a12e..8125a215 100644 --- a/SectionKit/Tests/SectionController/SectionDragDelegate/ProtocolDefaultValuesSectionDragDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionDragDelegate/ProtocolDefaultValuesSectionDragDelegateTests.swift @@ -3,6 +3,7 @@ import XCTest @available(iOS 11.0, *) internal final class ProtocolDefaultValuesSectionDragDelegateTests: BaseSectionDragDelegateTests { + @MainActor override func createSectionDragDelegate() throws -> SectionDragDelegate { class DefaultSectionDragDelegate: SectionDragDelegate { func dragItems( diff --git a/SectionKit/Tests/SectionController/SectionDropDelegate/BaseSectionControllerSectionDropDelegateTests.swift b/SectionKit/Tests/SectionController/SectionDropDelegate/BaseSectionControllerSectionDropDelegateTests.swift index 7ca0e2a3..aebb9d34 100644 --- a/SectionKit/Tests/SectionController/SectionDropDelegate/BaseSectionControllerSectionDropDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionDropDelegate/BaseSectionControllerSectionDropDelegateTests.swift @@ -1,9 +1,9 @@ import SectionKit import XCTest -@MainActor @available(iOS 11.0, *) -internal final class BaseSectionControllerSectionDropDelegateTests: BaseSectionDropDelegateTests { +final class BaseSectionControllerSectionDropDelegateTests: BaseSectionDropDelegateTests { + @MainActor override func createSectionDropDelegate() throws -> SectionDropDelegate { BaseSectionController() } diff --git a/SectionKit/Tests/SectionController/SectionDropDelegate/BaseSectionDropDelegateTests.swift b/SectionKit/Tests/SectionController/SectionDropDelegate/BaseSectionDropDelegateTests.swift index c9977495..fe3b26d4 100644 --- a/SectionKit/Tests/SectionController/SectionDropDelegate/BaseSectionDropDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionDropDelegate/BaseSectionDropDelegateTests.swift @@ -1,25 +1,26 @@ import SectionKit import XCTest -@MainActor @available(iOS 11.0, *) -internal class BaseSectionDropDelegateTests: XCTestCase { +class BaseSectionDropDelegateTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { + func skipIfNeeded() throws { guard Self.self === BaseSectionDropDelegateTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createSectionDropDelegate() throws -> SectionDropDelegate { + @MainActor + func createSectionDropDelegate() throws -> SectionDropDelegate { throw XCTSkip("Tests from base class are skipped") } - internal func testCanHandle() throws { + @MainActor + func testCanHandle() throws { let sectionDropDelegate = try createSectionDropDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -33,7 +34,8 @@ internal class BaseSectionDropDelegateTests: XCTestCase { )) } - internal func testDropSessionDidUpdate() throws { + @MainActor + func testDropSessionDidUpdate() throws { let sectionDropDelegate = try createSectionDropDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -52,7 +54,8 @@ internal class BaseSectionDropDelegateTests: XCTestCase { ) } - internal func testPerformDrop() throws { + @MainActor + func testPerformDrop() throws { let sectionDropDelegate = try createSectionDropDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -68,7 +71,8 @@ internal class BaseSectionDropDelegateTests: XCTestCase { ) } - internal func testDropSessionDidEnter() throws { + @MainActor + func testDropSessionDidEnter() throws { let sectionDropDelegate = try createSectionDropDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -82,7 +86,8 @@ internal class BaseSectionDropDelegateTests: XCTestCase { ) } - internal func testDropSessionDidExit() throws { + @MainActor + func testDropSessionDidExit() throws { let sectionDropDelegate = try createSectionDropDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -96,7 +101,8 @@ internal class BaseSectionDropDelegateTests: XCTestCase { ) } - internal func testDropSessionDidEnd() throws { + @MainActor + func testDropSessionDidEnd() throws { let sectionDropDelegate = try createSectionDropDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -110,7 +116,8 @@ internal class BaseSectionDropDelegateTests: XCTestCase { ) } - internal func testDropPreviewParametersForItem() throws { + @MainActor + func testDropPreviewParametersForItem() throws { let sectionDropDelegate = try createSectionDropDelegate() let context = MainCollectionViewContext( viewController: nil, diff --git a/SectionKit/Tests/SectionController/SectionDropDelegate/ProtocolDefaultValuesSectionDropDelegateTests.swift b/SectionKit/Tests/SectionController/SectionDropDelegate/ProtocolDefaultValuesSectionDropDelegateTests.swift index 838d6eca..1d063d82 100644 --- a/SectionKit/Tests/SectionController/SectionDropDelegate/ProtocolDefaultValuesSectionDropDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionDropDelegate/ProtocolDefaultValuesSectionDropDelegateTests.swift @@ -1,9 +1,9 @@ import SectionKit import XCTest -@MainActor @available(iOS 11.0, *) internal final class ProtocolDefaultValuesSectionDropDelegateTests: BaseSectionDropDelegateTests { + @MainActor override func createSectionDropDelegate() throws -> SectionDropDelegate { class DefaultSectionDropDelegate: SectionDropDelegate { func performDrop( diff --git a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionControllerSectionFlowDelegateTests.swift b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift similarity index 54% rename from SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionControllerSectionFlowDelegateTests.swift rename to SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift index 6624c139..d26ce6e2 100644 --- a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionControllerSectionFlowDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift @@ -1,8 +1,8 @@ import SectionKit import XCTest -@MainActor -internal final class BaseSectionControllerSectionFlowDelegateTests: BaseSectionFlowDelegateTests { +final class BaseFlowLayoutSectionControllerSectionFlowDelegateTests: BaseFlowLayoutSectionFlowDelegateTests { + @MainActor override func createSectionFlowDelegate() throws -> SectionFlowDelegate { BaseSectionController() } diff --git a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionFlowDelegateTests.swift b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionFlowDelegateTests.swift similarity index 87% rename from SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionFlowDelegateTests.swift rename to SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionFlowDelegateTests.swift index d6700d55..18d6a8ce 100644 --- a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionFlowDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionFlowDelegateTests.swift @@ -1,24 +1,25 @@ import SectionKit import XCTest -@MainActor -internal class BaseSectionFlowDelegateTests: XCTestCase { +class BaseFlowLayoutSectionFlowDelegateTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false try skipIfNeeded() } - internal func skipIfNeeded() throws { - guard Self.self === BaseSectionFlowDelegateTests.self else { return } + func skipIfNeeded() throws { + guard Self.self === BaseFlowLayoutSectionFlowDelegateTests.self else { return } throw XCTSkip("Tests from base class are skipped") } - internal func createSectionFlowDelegate() throws -> SectionFlowDelegate { + @MainActor + func createSectionFlowDelegate() throws -> SectionFlowDelegate { throw XCTSkip("Tests from base class are skipped") } - internal func testSizeForItemWithFlowLayout() throws { + @MainActor + func testSizeForItemWithFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -39,7 +40,8 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } - internal func testSizeForItemWithoutFlowLayout() throws { + @MainActor + func testSizeForItemWithoutFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -58,7 +60,8 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } - internal func testInsetWithFlowLayout() throws { + @MainActor + func testInsetWithFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -77,7 +80,8 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } - internal func testInsetWithoutFlowLayout() throws { + @MainActor + func testInsetWithoutFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -94,7 +98,8 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } - internal func testMinimumLineSpacingWithFlowLayout() throws { + @MainActor + func testMinimumLineSpacingWithFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -112,7 +117,8 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } - internal func testMinimumLineSpacingWithoutFlowLayout() throws { + @MainActor + func testMinimumLineSpacingWithoutFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -129,7 +135,8 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } - internal func testMinimumInteritemSpacingWithFlowLayout() throws { + @MainActor + func testMinimumInteritemSpacingWithFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -147,7 +154,8 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } - internal func testMinimumInteritemSpacingWithoutFlowLayout() throws { + @MainActor + func testMinimumInteritemSpacingWithoutFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -164,7 +172,8 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } - internal func testReferenceSizeForHeaderWithFlowLayout() throws { + @MainActor + func testReferenceSizeForHeaderWithFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -183,7 +192,8 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } - internal func testReferenceSizeForHeaderWithoutFlowLayout() throws { + @MainActor + func testReferenceSizeForHeaderWithoutFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -200,7 +210,8 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } - internal func testReferenceSizeForFooterWithFlowLayout() throws { + @MainActor + func testReferenceSizeForFooterWithFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( viewController: nil, @@ -219,7 +230,8 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } - internal func testReferenceSizeForFooterWithoutFlowLayout() throws { + @MainActor + func testReferenceSizeForFooterWithoutFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( viewController: nil, diff --git a/SectionKit/Tests/SectionController/SectionFlowDelegate/ProtocolDefaultValuesSectionFlowDelegateTests.swift b/SectionKit/Tests/SectionController/SectionFlowDelegate/ProtocolDefaultValuesSectionFlowDelegateTests.swift index 11d7246e..e464fc03 100644 --- a/SectionKit/Tests/SectionController/SectionFlowDelegate/ProtocolDefaultValuesSectionFlowDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionFlowDelegate/ProtocolDefaultValuesSectionFlowDelegateTests.swift @@ -1,8 +1,8 @@ import SectionKit import XCTest -@MainActor -internal final class ProtocolDefaultValuesSectionFlowDelegateTests: BaseSectionFlowDelegateTests { +final class ProtocolDefaultValuesSectionFlowDelegateTests: BaseFlowLayoutSectionFlowDelegateTests { + @MainActor override func createSectionFlowDelegate() throws -> SectionFlowDelegate { class DefaultSectionFlowDelegate: SectionFlowDelegate { } return DefaultSectionFlowDelegate() diff --git a/SectionKit/Tests/SectionController/SingleItemSectionControllerTests.swift b/SectionKit/Tests/SectionController/SingleItemSectionControllerTests.swift index 4077f3ee..fced1a85 100644 --- a/SectionKit/Tests/SectionController/SingleItemSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/SingleItemSectionControllerTests.swift @@ -1,15 +1,16 @@ @testable import SectionKit import XCTest -@MainActor -internal final class SingleItemSectionControllerTests: XCTestCase { - internal func testDidUpdateModelWithValidTypeSetsModel() { +final class SingleItemSectionControllerTests: XCTestCase { + @MainActor + func testDidUpdateModelWithValidTypeSetsModel() { let sectionController = SingleItemSectionController(model: "1") sectionController.didUpdate(model: "2") XCTAssertEqual(sectionController.model, "2") } - internal func testDidUpdateModelWithInvalidType() { + @MainActor + func testDidUpdateModelWithInvalidType() { let errorExpectation = expectation(description: "The errorHandler should be called") let sectionController = SingleItemSectionController(model: "1") let context = MainCollectionViewContext( @@ -32,7 +33,8 @@ internal final class SingleItemSectionControllerTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testInitDoesNotUpdateItemIfShouldNotUpdateItem() { + @MainActor + func testInitDoesNotUpdateItemIfShouldNotUpdateItem() { class TestSectionController: SingleItemSectionController { var itemsForModelExpectation: XCTestExpectation? @@ -56,7 +58,8 @@ internal final class SingleItemSectionControllerTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testSettingModelDoesNotUpdateItemIfShouldNotUpdateItem() { + @MainActor + func testSettingModelDoesNotUpdateItemIfShouldNotUpdateItem() { class TestSectionController: SingleItemSectionController { var itemsForModelExpectation: XCTestExpectation? @@ -83,12 +86,14 @@ internal final class SingleItemSectionControllerTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testShouldUpdateItemDefaultsToTrue() { + @MainActor + func testShouldUpdateItemDefaultsToTrue() { let sectionController = SingleItemSectionController(model: "1") XCTAssert(sectionController.shouldUpdateItem(afterModelChangedTo: "2")) } - internal func testItemForModelInvokesNotImplementedError() { + @MainActor + func testItemForModelInvokesNotImplementedError() { let errorExpectation = expectation(description: "The errorHandler should be called") let sectionController = SingleItemSectionController(model: "1") let context = MainCollectionViewContext( @@ -108,7 +113,8 @@ internal final class SingleItemSectionControllerTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testCalculateUpdateFromSomeToSomeWithEqualItems() throws { + @MainActor + func testCalculateUpdateFromSomeToSomeWithEqualItems() throws { let sectionController = SingleItemSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( @@ -125,7 +131,8 @@ internal final class SingleItemSectionControllerTests: XCTestCase { XCTAssertFalse(update.shouldReload(batchOperation)) } - internal func testCalculateUpdateFromSomeToSomeWithDifferentItems() throws { + @MainActor + func testCalculateUpdateFromSomeToSomeWithDifferentItems() throws { let sectionController = SingleItemSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( @@ -142,7 +149,8 @@ internal final class SingleItemSectionControllerTests: XCTestCase { XCTAssertFalse(update.shouldReload(batchOperation)) } - internal func testCalculateUpdateFromNoneToSome() throws { + @MainActor + func testCalculateUpdateFromNoneToSome() throws { let sectionController = SingleItemSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( @@ -159,7 +167,8 @@ internal final class SingleItemSectionControllerTests: XCTestCase { XCTAssertFalse(update.shouldReload(batchOperation)) } - internal func testCalculateUpdateFromSomeToNone() throws { + @MainActor + func testCalculateUpdateFromSomeToNone() throws { let sectionController = SingleItemSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( @@ -176,7 +185,8 @@ internal final class SingleItemSectionControllerTests: XCTestCase { XCTAssertFalse(update.shouldReload(batchOperation)) } - internal func testCalculateUpdateFromNoneToNone() throws { + @MainActor + func testCalculateUpdateFromNoneToNone() throws { let sectionController = SingleItemSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( @@ -193,7 +203,8 @@ internal final class SingleItemSectionControllerTests: XCTestCase { XCTAssertFalse(update.shouldReload(batchOperation)) } - internal func testNumberOfItemsWithItem() { + @MainActor + func testNumberOfItemsWithItem() { let sectionController = SingleItemSectionController(model: "1") sectionController.item = "1" let context = MainCollectionViewContext( @@ -204,7 +215,8 @@ internal final class SingleItemSectionControllerTests: XCTestCase { XCTAssertEqual(sectionController.numberOfItems(in: context), 1) } - internal func testNumberOfItemsWithoutItem() { + @MainActor + func testNumberOfItemsWithoutItem() { let sectionController = SingleItemSectionController(model: "1") sectionController.item = nil let context = MainCollectionViewContext( diff --git a/SectionKit/Tests/SectionController/SingleModelSectionControllerTests.swift b/SectionKit/Tests/SectionController/SingleModelSectionControllerTests.swift index 15c142e9..88b29c62 100644 --- a/SectionKit/Tests/SectionController/SingleModelSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/SingleModelSectionControllerTests.swift @@ -1,15 +1,16 @@ @testable import SectionKit import XCTest -@MainActor -internal final class SingleModelSectionControllerTests: XCTestCase { - internal func testDidUpdateModelWithValidTypeSetsModel() { +final class SingleModelSectionControllerTests: XCTestCase { + @MainActor + func testDidUpdateModelWithValidTypeSetsModel() { let sectionController = SingleModelSectionController(model: "1") sectionController.didUpdate(model: "2") XCTAssertEqual(sectionController.model, "2") } - internal func testDidUpdateModelWithInvalidType() { + @MainActor + func testDidUpdateModelWithInvalidType() { let errorExpectation = expectation(description: "The errorHandler should be called") let sectionController = SingleModelSectionController(model: "1") let context = MainCollectionViewContext( @@ -32,7 +33,8 @@ internal final class SingleModelSectionControllerTests: XCTestCase { waitForExpectations(timeout: 1) } - internal func testCalculateUpdateFromSomeToSomeWithDifferentItems() throws { + @MainActor + func testCalculateUpdateFromSomeToSomeWithDifferentItems() throws { let sectionController = SingleModelSectionController(model: 1) let update = try XCTUnwrap( sectionController.calculateUpdate( @@ -49,7 +51,8 @@ internal final class SingleModelSectionControllerTests: XCTestCase { XCTAssert(update.shouldReload(batchOperation)) } - internal func testNumberOfItems() { + @MainActor + func testNumberOfItems() { let sectionController = SingleModelSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, diff --git a/SectionKit/Tests/TestUtilities/MockSectionController.swift b/SectionKit/Tests/TestUtilities/MockSectionController.swift index f787dbf6..f5ffef42 100644 --- a/SectionKit/Tests/TestUtilities/MockSectionController.swift +++ b/SectionKit/Tests/TestUtilities/MockSectionController.swift @@ -42,6 +42,12 @@ internal class MockSectionController: SectionController { return MockErrorHandler() }() + @available(iOS 13.0, *) + internal lazy var layoutProvider: SectionLayoutProvider = { + XCTFail("layoutProvider is not set") + return .flowLayout(nil) + }() + // MARK: - didUpdate internal typealias DidUpdateBlock = (Any) -> Void diff --git a/SectionKit/Tests/Utility/UICollectionViewApplyTests.swift b/SectionKit/Tests/Utility/UICollectionViewApplyTests.swift index e65b61dd..1e75842b 100644 --- a/SectionKit/Tests/Utility/UICollectionViewApplyTests.swift +++ b/SectionKit/Tests/Utility/UICollectionViewApplyTests.swift @@ -1,11 +1,11 @@ @testable import SectionKit import XCTest -@MainActor -internal final class UICollectionViewApplyTests: XCTestCase { +final class UICollectionViewApplyTests: XCTestCase { // MARK: - CollectionViewSectionUpdate - internal func testSectionUpdateEmptyBatchOperations() { + @MainActor + func testSectionUpdateEmptyBatchOperations() { let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let update = CollectionViewSectionUpdate( controller: BaseSectionController(), @@ -15,7 +15,8 @@ internal final class UICollectionViewApplyTests: XCTestCase { collectionView.apply(update: update, at: 0) } - internal func testSectionUpdateWithoutWindowWithSingleBatchOperation() { + @MainActor + func testSectionUpdateWithoutWindowWithSingleBatchOperation() { let setDataExpectation = expectation(description: "Should invoke setData") let reloadDataExpectation = expectation(description: "Should invoke reloadData") let completionExpectation = expectation(description: "Should invoke completion of batch operation") @@ -51,7 +52,8 @@ internal final class UICollectionViewApplyTests: XCTestCase { ) } - internal func testSectionUpdateWithoutWindowWithMultipleBatchOperations() { + @MainActor + func testSectionUpdateWithoutWindowWithMultipleBatchOperations() { let firstSetDataExpectation = expectation(description: "Should invoke setData for first data") let secondSetDataExpectation = expectation(description: "Should invoke setData for second data") let reloadDataExpectation = expectation(description: "Should invoke reloadData") @@ -106,7 +108,8 @@ internal final class UICollectionViewApplyTests: XCTestCase { ) } - internal func testSectionUpdateWithWindowWithSingleBatchOperationWithAlwaysReload() { + @MainActor + func testSectionUpdateWithWindowWithSingleBatchOperationWithAlwaysReload() { let performBatchUpdatesExpectation = expectation(description: "Should invoke performBatchUpdates") let setDataExpectation = expectation(description: "Should invoke setData") let reloadSectionsExpectation = expectation(description: "Should invoke reloadSections") @@ -163,7 +166,8 @@ internal final class UICollectionViewApplyTests: XCTestCase { ) } - internal func testSectionUpdateWithWindowWithSingleBatchOperationWithSeparateUpdates() { + @MainActor + func testSectionUpdateWithWindowWithSingleBatchOperationWithSeparateUpdates() { let performBatchUpdatesExpectation = expectation(description: "Should invoke performBatchUpdates") let setDataExpectation = expectation(description: "Should invoke setData") let deleteItemsExpectation = expectation(description: "Should invoke deleteItems") @@ -264,7 +268,8 @@ internal final class UICollectionViewApplyTests: XCTestCase { // MARK: - CollectionViewUpdate - internal func testUpdateEmptyBatchOperations() { + @MainActor + func testUpdateEmptyBatchOperations() { let collectionView = MockCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) let update = CollectionViewUpdate( batchOperations: [], @@ -308,7 +313,8 @@ internal final class UICollectionViewApplyTests: XCTestCase { ) } - internal func testUpdateWithoutWindowWithMultipleBatchOperations() { + @MainActor + func testUpdateWithoutWindowWithMultipleBatchOperations() { let firstSetDataExpectation = expectation(description: "Should invoke setData for first data") let secondSetDataExpectation = expectation(description: "Should invoke setData for second data") let reloadDataExpectation = expectation(description: "Should invoke reloadData") @@ -361,7 +367,8 @@ internal final class UICollectionViewApplyTests: XCTestCase { ) } - internal func testUpdateWithWindowWithSingleBatchOperationWithAlwaysReload() { + @MainActor + func testUpdateWithWindowWithSingleBatchOperationWithAlwaysReload() { let setDataExpectation = expectation(description: "Should invoke setData") let reloadDataExpectation = expectation(description: "Should invoke reloadData") let completionExpectation = expectation(description: "Should invoke completion of batch operation") @@ -408,7 +415,8 @@ internal final class UICollectionViewApplyTests: XCTestCase { ) } - internal func testUpdateWithWindowWithSingleBatchOperationWithSeparateUpdates() { + @MainActor + func testUpdateWithWindowWithSingleBatchOperationWithSeparateUpdates() { let performBatchUpdatesExpectation = expectation(description: "Should invoke performBatchUpdates") let setDataExpectation = expectation(description: "Should invoke setData") let deleteSectionsExpectation = expectation(description: "Should invoke deleteSections")