Esempio n. 1
0
                public Enumerator(LifecycleTrackingEnumerable <T> enumerable)
                {
                    _enumerable = enumerable;

                    Interlocked.Increment(ref _enumerable._enumeratorCtorCalls);
                    _enumerator = enumerable._source.GetEnumerator();
                }
Esempio n. 2
0
        public void UnaryOperations_SourceEnumeratorDisposed()
        {
            // Using Assert.All instead of a Theory to avoid overloading the system with hundreds of thousands of distinct test cases.
            IEnumerable <(Source source, Unary unary1, Unary unary2, Sink sink)> inputs =
                from source in Sources()
                from unary1 in UnaryOperations()
                from unary2 in UnaryOperations()
                from sink in Sinks()
                select(source, unary1, unary2, sink);

            Assert.All(inputs, input =>
            {
                var(source, unary1, unary2, sink) = input;
                var e = new LifecycleTrackingEnumerable <int>(source.Work);

                // source -> unary1 -> unary2 -> sink
                bool argError = false;
                try
                {
                    sink.Work(unary2.Work(unary1.Work(e)));
                }
                catch (Exception exc) when(exc is ArgumentException || exc is InvalidOperationException)
                {
                    argError = true;
                }

                // We expect the source's enumerator should have been constructed 0 or 1 times,
                // once if there's no short-circuiting involved.  Then the enumerator's Dispose
                // should have been invoked the same number of times.
                bool shortCircuits = argError || ShortCircuits(source, unary1, unary2, sink);
                Assert.InRange(e.EnumeratorCtorCalls, shortCircuits ? 0 : 1, 1);
                Assert.Equal(e.EnumeratorCtorCalls, e.EnumeratorDisposeCalls);
            });
        }