/// <summary> /// Initializes a new instance of the <see cref="RefArgumentConstraint" /> class by /// wrapping an existing <see cref="IArgumentConstraint"/>. /// </summary> /// <param name="baseConstraint">The original constraint, which will be used for argument validation.</param> /// <param name="value">The value to be used when implicitly assigning values to a call's ref parameter.</param> public RefArgumentConstraint(IArgumentConstraint baseConstraint, object?value) { Guard.AgainstNull(baseConstraint, nameof(baseConstraint)); this.baseConstraint = baseConstraint; this.Value = value; }
public static void ReportTrappedConstraint(IArgumentConstraint constraint) { if (trappedConstraints != null) { trappedConstraints.Add(constraint); } }
/// <summary> /// Initializes a new instance of the <see cref="RefArgumentConstraint" /> class by /// wrapping an existing <see cref="IArgumentConstraint"/>. /// </summary> /// <param name="baseConstraint">The original constraint, which will be used for argument validation.</param> /// <param name="value">The value to be used when implicitly assigning values to a call's ref parameter.</param> public RefArgumentConstraint(IArgumentConstraint baseConstraint, object value) { Guard.AgainstNull(baseConstraint, "baseConstraint"); this.baseConstraint = baseConstraint; this.Value = value; }
public static void ReportTrappedConstraint(IArgumentConstraint constraint) { if (trappedConstraints == null) { throw new InvalidOperationException("A<T>.Ignored, A<T>._, and A<T>.That can only be used in the context of a call specification with A.CallTo()"); } trappedConstraints.Add(constraint); }
public void Should_track_constraints_supplied_in_calls_made_from_overlapping_threads() { // Ensures that constraints are properly trapped even when two constraint-trapping threads // overlap. Uses the reset events to ensure that the threads consistently execute like this: // |-----------------------------| // |---------------| // The thread that starts first will register to trap constraints before the second thread // but will not actually report the constraint until after the second thread has reported // its constraint and finished. // Without per-thread constraint trapping, this would mean that the first thread's constraint // would be lost. // Arrange var lateStartingLock = new ManualResetEventSlim(false); var lateEndingLock = new ManualResetEventSlim(false); var earlyStartingConstraint = A.Fake <IArgumentConstraint>(); A.CallTo(() => earlyStartingConstraint.ToString()).Returns("earlyStarter"); IArgumentConstraint earlyStartingResult = null; var lateStartingConstraint = A.Fake <IArgumentConstraint>(); A.CallTo(() => lateStartingConstraint.ToString()).Returns("lateStarter"); IArgumentConstraint lateStartingResult = null; // Act var earlyStartingTask = Task.Run(() => { earlyStartingResult = this.trap.TrapConstraintOrCreate( () => { lateStartingLock.Set(); lateEndingLock.Wait(); ArgumentConstraintTrap.ReportTrappedConstraint(earlyStartingConstraint); }, UnusedConstraintFactory); }); var lateStartingTask = Task.Run(() => { lateStartingLock.Wait(); lateStartingResult = this.trap.TrapConstraintOrCreate( () => ArgumentConstraintTrap.ReportTrappedConstraint(lateStartingConstraint), UnusedConstraintFactory); lateEndingLock.Set(); }); Task.WaitAll(earlyStartingTask, lateStartingTask); // Assert new[] { earlyStartingResult, lateStartingResult } .Should().Equal(earlyStartingConstraint, lateStartingConstraint); }
public static INestedArgumentConstraint Check(this IArgumentConstraint constraint) { if (constraint != null) { if (!constraint.Exceptions.Skip(1).Any()) { throw constraint.Exceptions.Single(); } throw new AggregateException("Argument validation failed for several reasons.", constraint.Exceptions); } return(null); }
/// <summary> /// Initializes a new instance of the <see cref="ExpressionCallMatcher" /> class. /// </summary> /// <param name="parsedExpression">The parsed call specification.</param> /// <param name="constraintFactory">The constraint factory.</param> /// <param name="methodInfoManager">The method info manager to use.</param> public ExpressionCallMatcher(ParsedCallExpression parsedExpression, ExpressionArgumentConstraintFactory constraintFactory, MethodInfoManager methodInfoManager) { this.methodInfoManager = methodInfoManager; this.Method = parsedExpression.CalledMethod; var constraints = new IArgumentConstraint[parsedExpression.ArgumentsExpressions.Length]; for (var i = 0; i < constraints.Length; i++) { constraints[i] = constraintFactory.GetArgumentConstraint(parsedExpression.ArgumentsExpressions[i]); } this.argumentConstraints = constraints; this.argumentsPredicate = this.ArgumentsMatchesArgumentConstraints; }
public void SetUp() { this.createdConstraint = null; this.constraintManager = new DefaultArgumentConstraintManager<string>(x => this.createdConstraint = x); }
public static string TooManyArgumentConstraints(IArgumentConstraint constraint) => $"Too many argument constraints specified. First superfluous constraint is {constraint}.";
public DefaultArgumentConstraintManagerTests() { this.createdConstraint = null; this.constraintManager = new DefaultArgumentConstraintManager <string>(x => this.createdConstraint = x); }
public static IArgumentConstraint IsOfType <TA>(this IArgumentConstraint constraint, object parameter, string parameterName) { return(parameter is TA ? constraint : constraint.AddException(new ArgumentException($"'{parameterName}' must be of the type '{typeof(TA)}', but was of type '{parameter.GetType()}'.", parameterName))); }
public static void ReportTrappedConstraint(IArgumentConstraint constraint) => saveTrappedConstraintAction.Value.Invoke(constraint);
public DefaultArgumentConstraintManagerTests() { this.createdConstraint = null !; // it will be assigned a non-null value by the time it's accessed this.constraintManager = new DefaultArgumentConstraintManager <string>(x => this.createdConstraint = x); }