@@ -126,5 +126,89 @@ public void NullPredicate_ThrowsArgumentNullException()
126126 Func < int , bool > predicate = null ;
127127 AssertExtensions . Throws < ArgumentNullException > ( "predicate" , ( ) => Enumerable . Range ( 0 , 3 ) . Count ( predicate ) ) ;
128128 }
129+
130+ [ Fact ]
131+ public void NonEnumeratingCount_NullSource_ThrowsArgumentNullException ( )
132+ {
133+ AssertExtensions . Throws < ArgumentNullException > ( "source" , ( ) => ( ( IEnumerable < int > ) null ) . TryGetNonEnumeratedCount ( out _ ) ) ;
134+ }
135+
136+ [ Theory ]
137+ [ MemberData ( nameof ( NonEnumeratingCount_SupportedEnumerables ) ) ]
138+ public void NonEnumeratingCount_SupportedEnumerables_ShouldReturnExpectedCount < T > ( int expectedCount , IEnumerable < T > source )
139+ {
140+ Assert . True ( source . TryGetNonEnumeratedCount ( out int actualCount ) ) ;
141+ Assert . Equal ( expectedCount , actualCount ) ;
142+ }
143+
144+ [ Theory ]
145+ [ MemberData ( nameof ( NonEnumeratingCount_UnsupportedEnumerables ) ) ]
146+ public void NonEnumeratingCount_UnsupportedEnumerables_ShouldReturnFalse < T > ( IEnumerable < T > source )
147+ {
148+ Assert . False ( source . TryGetNonEnumeratedCount ( out int actualCount ) ) ;
149+ Assert . Equal ( 0 , actualCount ) ;
150+ }
151+
152+ [ Fact ]
153+ public void NonEnumeratingCount_ShouldNotEnumerateSource ( )
154+ {
155+ bool isEnumerated = false ;
156+ Assert . False ( Source ( ) . TryGetNonEnumeratedCount ( out int count ) ) ;
157+ Assert . Equal ( 0 , count ) ;
158+ Assert . False ( isEnumerated ) ;
159+
160+ IEnumerable < int > Source ( )
161+ {
162+ isEnumerated = true ;
163+ yield return 42 ;
164+ }
165+ }
166+
167+ public static IEnumerable < object [ ] > NonEnumeratingCount_SupportedEnumerables ( )
168+ {
169+ yield return WrapArgs ( 4 , new int [ ] { 1 , 2 , 3 , 4 } ) ;
170+ yield return WrapArgs ( 4 , new List < int > ( new int [ ] { 1 , 2 , 3 , 4 } ) ) ;
171+ yield return WrapArgs ( 4 , new Stack < int > ( new int [ ] { 1 , 2 , 3 , 4 } ) ) ;
172+
173+ yield return WrapArgs ( 0 , Enumerable . Empty < string > ( ) ) ;
174+
175+ if ( PlatformDetection . IsSpeedOptimized )
176+ {
177+ yield return WrapArgs ( 100 , Enumerable . Range ( 1 , 100 ) ) ;
178+ yield return WrapArgs ( 80 , Enumerable . Repeat ( 1 , 80 ) ) ;
179+ yield return WrapArgs ( 50 , Enumerable . Range ( 1 , 50 ) . Select ( x => x + 1 ) ) ;
180+ yield return WrapArgs ( 4 , new int [ ] { 1 , 2 , 3 , 4 } . Select ( x => x + 1 ) ) ;
181+ yield return WrapArgs ( 50 , Enumerable . Range ( 1 , 50 ) . Select ( x => x + 1 ) . Select ( x => x - 1 ) ) ;
182+ yield return WrapArgs ( 7 , Enumerable . Range ( 1 , 20 ) . ToLookup ( x => x % 7 ) ) ;
183+ yield return WrapArgs ( 20 , Enumerable . Range ( 1 , 20 ) . Reverse ( ) ) ;
184+ yield return WrapArgs ( 20 , Enumerable . Range ( 1 , 20 ) . OrderBy ( x => - x ) ) ;
185+ yield return WrapArgs ( 20 , Enumerable . Range ( 1 , 10 ) . Concat ( Enumerable . Range ( 11 , 10 ) ) ) ;
186+ }
187+
188+ static object [ ] WrapArgs < T > ( int expectedCount , IEnumerable < T > source ) => new object [ ] { expectedCount , source } ;
189+ }
190+
191+ public static IEnumerable < object [ ] > NonEnumeratingCount_UnsupportedEnumerables ( )
192+ {
193+ yield return WrapArgs ( Enumerable . Range ( 1 , 100 ) . Where ( x => x % 2 == 0 ) ) ;
194+ yield return WrapArgs ( Enumerable . Range ( 1 , 100 ) . GroupBy ( x => x % 2 == 0 ) ) ;
195+ yield return WrapArgs ( new Stack < int > ( new int [ ] { 1 , 2 , 3 , 4 } ) . Select ( x => x + 1 ) ) ;
196+ yield return WrapArgs ( Enumerable . Range ( 1 , 100 ) . Distinct ( ) ) ;
197+
198+ if ( ! PlatformDetection . IsSpeedOptimized )
199+ {
200+ yield return WrapArgs ( Enumerable . Range ( 1 , 100 ) ) ;
201+ yield return WrapArgs ( Enumerable . Repeat ( 1 , 80 ) ) ;
202+ yield return WrapArgs ( Enumerable . Range ( 1 , 50 ) . Select ( x => x + 1 ) ) ;
203+ yield return WrapArgs ( new int [ ] { 1 , 2 , 3 , 4 } . Select ( x => x + 1 ) ) ;
204+ yield return WrapArgs ( Enumerable . Range ( 1 , 50 ) . Select ( x => x + 1 ) . Select ( x => x - 1 ) ) ;
205+ yield return WrapArgs ( Enumerable . Range ( 1 , 20 ) . ToLookup ( x => x % 7 ) ) ;
206+ yield return WrapArgs ( Enumerable . Range ( 1 , 20 ) . Reverse ( ) ) ;
207+ yield return WrapArgs ( Enumerable . Range ( 1 , 20 ) . OrderBy ( x => - x ) ) ;
208+ yield return WrapArgs ( Enumerable . Range ( 1 , 10 ) . Concat ( Enumerable . Range ( 11 , 10 ) ) ) ;
209+ }
210+
211+ static object [ ] WrapArgs < T > ( IEnumerable < T > source ) => new object [ ] { source } ;
212+ }
129213 }
130214}
0 commit comments