static object ApplyPredicatesToEndOfChain(ref string path, Result result, IList <INamedPredicate> predicates, List <ChainStep> remainingChain) { ChainStep step; if (remainingChain.Count == 1) { step = remainingChain[0]; try { result.Target = result.Target.Get(step.Name); path += "." + step.Name; } catch (FastFailureException) { result.FailBecause(path + "." + step.Name + " is not a valid path"); return(null); } } else { step = ChainStep.SimpleStep("?"); } if (result.Target is IEnumerable) { ApplyPredicatesToTerminalEnumerable(path, result, predicates, step); } else { ApplyPredicatesToSimpleTerminal(path, result, predicates); } return(result.Target); }
/// <summary> /// Syntax: Check.That....child(enumeration spec) /// Add an enumeration spec to a path item. /// Cases: /// Singular, minima = either like `list(1)` or `list("any")`; /// All with predicate = like `list("all", o => o.something != null)` /// </summary> public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { // we've been passed an enumeration argument switch (args.Length) { case 1: // either like `list(1)` or `list("any")` if (args[0] is int) { result = Add(ChainStep.Complex(binder.Name, "index", (int)args[0], ChainStep.Anything)); } else { result = Add(ChainStep.Complex(binder.Name, args[0].ToString(), 0, ChainStep.Anything)); } break; case 2: // like `list("all", o => o.something != null)` result = Add(ChainStep.Complex(binder.Name, args[0].ToString(), 0, (INamedPredicate)args[1])); break; default: // don't understand! throw new ArgumentException("I don't understand the arguments to " + binder.Name); } return(true); }
/// <summary> /// Adds a method call to the sequence. /// </summary> /// <param name="method">The method to be added.</param> public ChainSequence AddMethod(Action method) { var step = new ChainStep(ChainStepType.METHOD, method); steps.Add(step); return(this); }
Check(object subject, IEnumerable <ChainStep> oldChain, ChainStep nextItem) { this.subject = subject; chain = new List <ChainStep>(oldChain) { nextItem }; }
/// <summary> /// Adds a delay to the sequence. /// </summary> /// <param name="delay">The delay in seconds.</param> public ChainSequence AddDelay(float delay) { times.Add(delay); Action action = StartDelay; var step = new ChainStep(ChainStepType.DELAY, action); steps.Add(step); return(this); }
static object[] FilterWithNamedPredicate(IEnumerable source, ChainStep step, out string message) { string stepMsg = ""; var container = source.Cast <object>().Where(o => step.FilterPredicate.Matches(o, out stepMsg)).ToArray(); message = (string.IsNullOrEmpty(stepMsg)) ? "" : "(Matching: " + stepMsg + ")"; return(container); }
static bool StepIndex(Result result, ChainStep step, object[] container, out object next, ref string pathHere) { next = null; if (step.SingleIndex < 0 || step.SingleIndex >= container.Length) { result.FailBecause(pathHere + " has length of " + container.Length + ", tried to access index " + step.SingleIndex); return(false); } pathHere += "[" + step.SingleIndex + "]"; next = container[step.SingleIndex]; return(true); }
static void ApplyPredicatesToTerminalEnumerable(string path, Result result, IList <INamedPredicate> predicates, ChainStep step) { string stepMsg; var container = FilterWithNamedPredicate((IEnumerable)result.Target, step, out stepMsg); path += stepMsg; object target; switch (step.ListAssertionType) { case ListAssertion.Simple: ApplyPredicatesToSimpleTerminal(path, result, predicates); break; case ListAssertion.Single: if (!StepSingle(result, path, container, out target)) { return; } var singleResult = new Result { Target = target }; ApplyPredicatesToSimpleTerminal(path, singleResult, predicates); result.Merge(singleResult); break; case ListAssertion.Index: if (!StepIndex(result, step, container, out target, ref path)) { return; } var indexResult = new Result { Target = target }; ApplyPredicatesToSimpleTerminal(path, indexResult, predicates); result.Merge(indexResult); break; case ListAssertion.All: CheckAll(result, predicates, path, container); return; case ListAssertion.Any: CheckAny(result, predicates, path, container); return; default: throw new Exception("Unexpected list assertion type"); } }
/// <summary> /// Syntax: .parent.child.grandchild /// Add a step in the path to validate /// </summary> public override bool TryGetMember(GetMemberBinder binder, out object result) { // No actual access here, just record the request. result = Add(ChainStep.SimpleStep(binder.Name)); return(true); }
dynamic Add(ChainStep name) { return(new Check(subject, chain, name)); }