Beispiel #1
0
 /// <summary>
 ///     Introduces an alternative branch that is used in lieu of the normal branch for a given number of uses.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'log' step is added.</param>
 /// <param name="times">The number of times the alternative branch should be used.</param>
 /// <param name="branch">An action to set up the alternative branch.</param>
 /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
 public static ICanHaveNextIndexerStep <TKey, TValue> Times <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller,
     int times,
     Action <ICanHaveNextIndexerStep <TKey, TValue> > branch)
 {
     return(caller.SetNextStep(new TimesIndexerStep <TKey, TValue>(times, branch)));
 }
Beispiel #2
0
 /// <summary>
 ///     Introduces a step that will remember ('store') values written to it, returning them when read. It uses a dictionary
 ///     for storage.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'stored' step is added.</param>
 /// <param name="step">
 ///     Returns the added step itself. It can be used to manipulate the store and check contents of the
 ///     store.
 /// </param>
 /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
 public static IStoredIndexer <TKey, TValue> StoredAsDictionary <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller,
     out StoredAsDictionaryIndexerStep <TKey, TValue> step)
 {
     step = new StoredAsDictionaryIndexerStep <TKey, TValue>();
     return(caller.SetNextStep(step));
 }
Beispiel #3
0
 /// <summary>
 ///     Introduces an alternative set of steps that can be chosen given the provided conditions, where the conditions can
 ///     depend on the state of the entire mock instance.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'conditional' step is added.</param>
 /// <param name="getCondition">
 ///     A condition evaluated when the indexer is read from. If <c>true</c>, the alternative branch
 ///     is taken.
 /// </param>
 /// <param name="setCondition">
 ///     A condition evaluated when the indexer is written to. If <c>true</c>, the alternative branch
 ///     is taken.
 /// </param>
 /// <param name="branch">
 ///     An action to set up the alternative branch; it also provides a means of re-joining the normal
 ///     branch.
 /// </param>
 /// <returns>
 ///     An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps on the normal
 ///     branch.
 /// </returns>
 public static ICanHaveNextIndexerStep <TKey, TValue> InstanceIf <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller,
     Func <object, TKey, bool>?getCondition,
     Func <object, TKey, TValue, bool>?setCondition,
     Action <IfIndexerStepBase <TKey, TValue> .IfBranchCaller> branch)
 {
     return(caller.SetNextStep(new InstanceIfIndexerStep <TKey, TValue>(getCondition, setCondition, branch)));
 }
Beispiel #4
0
        /// <summary>
        ///     Introduces a step whose only purpose is to be joined to from another step. It forwards all indexer reads and
        ///     writes.
        /// </summary>
        /// <typeparam name="TKey">The type of the indexer key.</typeparam>
        /// <typeparam name="TValue">The type of the indexer value.</typeparam>
        /// <param name="caller">The mock or step to which this 'join' step is added.</param>
        /// <param name="joinPoint">A reference to this step that can be used in a Join step.</param>
        /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
        public static ICanHaveNextIndexerStep <TKey, TValue> JoinPoint <TKey, TValue>(
            this ICanHaveNextIndexerStep <TKey, TValue> caller,
            out IIndexerStep <TKey, TValue> joinPoint)
        {
            var joinStep = new IndexerStepWithNext <TKey, TValue>();

            joinPoint = joinStep;
            return(caller.SetNextStep(joinStep));
        }
        /// <summary>
        ///     Introduces a step that will record an entry before a value as been written to the indexer.
        /// </summary>
        /// <typeparam name="TKey">The type of the indexer key.</typeparam>
        /// <typeparam name="TValue">The type of the indexer value.</typeparam>
        /// <typeparam name="TRecord">The type of the entries that will be recorded in the ledger.</typeparam>
        /// <param name="caller">The mock or step to which this 'record' step is added.</param>
        /// <param name="ledger">A list that contains recorded entries.</param>
        /// <param name="selector">
        ///     A Func that constructs an entry for when a value is written.
        ///     Takes the mocked instance, the key used and the value as parameters.
        /// </param>
        /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
        public static ICanHaveNextIndexerStep <TKey, TValue> InstanceRecordBeforeSet <TKey, TValue, TRecord>(
            this ICanHaveNextIndexerStep <TKey, TValue> caller,
            out IReadOnlyList <TRecord> ledger,
            Func <object, TKey, TValue, TRecord> selector)
        {
            var newStep = new InstanceRecordBeforeSetIndexerStep <TKey, TValue, TRecord>(selector);

            ledger = newStep;
            return(caller.SetNextStep(newStep));
        }
        /// <summary>
        ///     Introduces a step that will record an entry after a value is read from the indexer; optionally also recording
        ///     exceptions.
        /// </summary>
        /// <typeparam name="TKey">The type of the indexer key.</typeparam>
        /// <typeparam name="TValue">The type of the indexer value.</typeparam>
        /// <typeparam name="TRecord">The type of the entries that will be recorded in the ledger.</typeparam>
        /// <param name="caller">The mock or step to which this 'record' step is added.</param>
        /// <param name="ledger">A list that contains recorded entries.</param>
        /// <param name="successSelector">
        ///     A Func that constructs an entry for when a value has been read.
        ///     Takes the mocked instance, the key used and the value as parameters.
        /// </param>
        /// <param name="failureSelector">
        ///     An Func that constructs an entry for an exception thrown when reading a value.
        ///     Takes the mocked instance, the key used and the exception as parameters.
        /// </param>
        /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
        public static ICanHaveNextIndexerStep <TKey, TValue> InstanceRecordAfterGet <TKey, TValue, TRecord>(
            this ICanHaveNextIndexerStep <TKey, TValue> caller,
            out IReadOnlyList <TRecord> ledger,
            Func <object, TKey, TValue, TRecord>?successSelector,
            Func <object, TKey, Exception, TRecord>?failureSelector = null)
        {
            var newStep = new InstanceRecordAfterGetIndexerStep <TKey, TValue, TRecord>(successSelector, failureSelector);

            ledger = newStep;
            return(caller.SetNextStep(newStep));
        }
Beispiel #7
0
        /// <summary>
        ///     Introduces a step that logs all gets and sets of the mocked indexer to a log context, where
        ///     the log context is provided by an <see cref="ILogContextProvider" />.
        /// </summary>
        /// <typeparam name="TKey">The type of the indexer key.</typeparam>
        /// <typeparam name="TValue">The type of the indexer value.</typeparam>
        /// <param name="caller">The mock or step to which this 'log' step is added.</param>
        /// <param name="logContextProvider">An instance from which we can get an <see cref="ILogContext" /> to use.</param>
        /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
        public static ICanHaveNextIndexerStep <TKey, TValue> Log <TKey, TValue>(
            this ICanHaveNextIndexerStep <TKey, TValue> caller,
            ILogContextProvider logContextProvider)
        {
            if (logContextProvider == null)
            {
                throw new ArgumentNullException(nameof(logContextProvider));
            }

            return(caller.SetNextStep(new LogIndexerStep <TKey, TValue>(logContextProvider.LogContext)));
        }
        /// <summary>
        ///     Step that checks the number of times values have been read from or written to the indexer. Adds the check
        ///     to the verification group provided.
        /// </summary>
        /// <typeparam name="TKey">The type of the indexer key.</typeparam>
        /// <typeparam name="TValue">The type of the indexer value.</typeparam>
        /// <param name="caller">The mock or step to which this 'verification' step is added.</param>
        /// <param name="verificationGroup">The verification group to which this check is added.</param>
        /// <param name="name">A name that can be used to identify the check in its group.</param>
        /// <param name="expectedNumberOfGets">The expected number of times values have been read from the indexer.</param>
        /// <param name="expectedNumberOfSets">The expected number of times values have been written to the indexer.</param>
        /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
        public static ICanHaveNextIndexerStep <TKey, TValue> ExpectedUsage <TKey, TValue>(
            this ICanHaveNextIndexerStep <TKey, TValue> caller,
            VerificationGroup verificationGroup,
            string?name,
            int?expectedNumberOfGets = null,
            int?expectedNumberOfSets = null)
        {
            if (verificationGroup == null)
            {
                throw new ArgumentNullException(nameof(verificationGroup));
            }

            var step = new ExpectedUsageIndexerStep <TKey, TValue>(name, expectedNumberOfGets, expectedNumberOfSets);

            verificationGroup.Add(step);
            return(caller.SetNextStep(step));
        }
Beispiel #9
0
 /// <summary>
 ///     Introduces a step that will remember ('store') values written to it, returning them when read. It uses a dictionary
 ///     for storage.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'stored' step is added.</param>
 /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
 public static IStoredIndexer <TKey, TValue> StoredAsDictionary <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller)
 {
     return(caller.SetNextStep(new StoredAsDictionaryIndexerStep <TKey, TValue>()));
 }
Beispiel #10
0
 /// <summary>
 ///     Introduces an alternative set of steps that is chosen when the indexer is written to.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'conditional' step is added.</param>
 /// <param name="branch">
 ///     An action to set up the alternative branch; it also provides a means of re-joining the normal
 ///     branch.
 /// </param>
 /// <returns>
 ///     An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps on the normal
 ///     branch.
 /// </returns>
 public static ICanHaveNextIndexerStep <TKey, TValue> IfSet <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller,
     Action <IfIndexerStepBase <TKey, TValue> .IfBranchCaller> branch)
 {
     return(caller.SetNextStep(new IfSetIndexerStep <TKey, TValue>(branch)));
 }
Beispiel #11
0
 /// <summary>
 ///     Introduces a step that returns values from a list one-by-one when read, while passing on any writes to subsequent
 ///     steps. It will also
 ///     pass on reads once the list has been exhausted.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'return' step is added.</param>
 /// <param name="values">The values to be returned one-by-one.</param>
 /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
 public static ICanHaveNextIndexerStep <TKey, TValue> ReturnEach <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller,
     IEnumerable <TValue> values)
 {
     return(caller.SetNextStep(new ReturnEachIndexerStep <TKey, TValue>(values)));
 }
Beispiel #12
0
 /// <summary>
 ///     Introduces a step that will throw a <see cref="MockMissingException" /> whenever the indexer is read from or
 ///     written to.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'missing' step is added.</param>
 public static void Missing <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller)
 {
     caller.SetNextStep(MissingIndexerStep <TKey, TValue> .Instance);
 }
Beispiel #13
0
 /// <summary>
 ///     Introduces a step that returns a given value the first time it is read, while passing on any writes and further
 ///     reads to subsequent steps.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'return' step is added.</param>
 /// <param name="value">The value to be returned.</param>
 /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
 public static ICanHaveNextIndexerStep <TKey, TValue> ReturnOnce <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller,
     TValue value)
 {
     return(caller.SetNextStep(new ReturnOnceIndexerStep <TKey, TValue>(value)));
 }
Beispiel #14
0
 public FakeNextIndexerStep(ICanHaveNextIndexerStep <TKey, TValue> mock, TValue value)
 {
     _value = value;
     mock.SetNextStep(this);
 }
Beispiel #15
0
 /// <summary>
 ///     Introduces a step that will forward getting and setting indexer values to another step.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'join' step is added.</param>
 /// <param name="joinPoint">The step to which getting and setting indexer values will be forwarded.</param>
 public static void Join <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller,
     IIndexerStep <TKey, TValue> joinPoint)
 {
     caller.SetNextStep(joinPoint);
 }
Beispiel #16
0
 /// <summary>
 ///     Introduces a step that will get values by calculating them from the key, while forwarding setting of values to a
 ///     next step.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'lambda' step is added.</param>
 /// <param name="func">The function used to calculate the value from the key.</param>
 /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
 public static ICanHaveNextIndexerStep <TKey, TValue> GetFunc <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller,
     Func <TKey, TValue> func)
 {
     return(caller.SetNextStep(new GetFuncIndexerStep <TKey, TValue>(func)));
 }
Beispiel #17
0
 /// <summary>
 ///     Introduces a filter that will only progress to writing a value if it's different from the current value.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'conditional' step is added.</param>
 /// <param name="comparer">
 ///     An optional <see cref="IEqualityComparer{TValue}" /> that is used to determine whether the new
 ///     value is different from the current one.
 /// </param>
 /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
 public static ICanHaveNextIndexerStep <TKey, TValue> OnlySetIfChanged <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller,
     IEqualityComparer <TValue>?comparer = null)
 {
     return(caller.SetNextStep(new OnlySetIfChangedIndexerStep <TKey, TValue>(comparer)));
 }
Beispiel #18
0
 /// <summary>
 ///     Introduces a step that will invoke an action whenever a value is set, while forwarding getting of values to a
 ///     next step.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'lambda' step is added.</param>
 /// <param name="action">The action to be invoked when a value is set.</param>
 /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
 public static ICanHaveNextIndexerStep <TKey, TValue> InstanceSetAction <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller,
     Action <object, TKey, TValue> action)
 {
     return(caller.SetNextStep(new InstanceSetActionIndexerStep <TKey, TValue>(action)));
 }
Beispiel #19
0
 /// <summary>
 ///     Introduces a step that logs all gets and sets of the mocked indexer to a log context, or the console if none was
 ///     provided.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'log' step is added.</param>
 /// <param name="logContext">
 ///     The <see cref="ILogContext" /> used to write the log entries. The default will write to the
 ///     console.
 /// </param>
 /// <returns>An <see cref="ICanHaveNextIndexerStep{TKey, TValue}" /> that can be used to add further steps.</returns>
 public static ICanHaveNextIndexerStep <TKey, TValue> Log <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller,
     ILogContext?logContext = null)
 {
     return(caller.SetNextStep(new LogIndexerStep <TKey, TValue>(logContext ?? WriteLineLogContext.Console)));
 }
Beispiel #20
0
 /// <summary>
 ///     Introduces a step that will throw an exception whenever a value is written to or read from the indexer.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'throw' step is added.</param>
 /// <param name="exceptionFactory">
 ///     A Func that creates the exception to be thrown. Takes the mocked instance and indexer
 ///     key as parameters.
 /// </param>
 public static void InstanceThrow <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller,
     Func <object, TKey, Exception> exceptionFactory)
 {
     caller.SetNextStep(new ThrowIndexerStep <TKey, TValue>(exceptionFactory));
 }
Beispiel #21
0
 /// <summary>
 ///     Introduces a step that will ignore all writes and return default values for all reads.
 /// </summary>
 /// <typeparam name="TKey">The type of the indexer key.</typeparam>
 /// <typeparam name="TValue">The type of the indexer value.</typeparam>
 /// <param name="caller">The mock or step to which this 'dummy' step is added.</param>
 public static void Dummy <TKey, TValue>(
     this ICanHaveNextIndexerStep <TKey, TValue> caller)
 {
     caller.SetNextStep(DummyIndexerStep <TKey, TValue> .Instance);
 }