public void ShouldThrowExceptionOnInitializationIfCalledWithTheSameMethodCallId()
    {
      const int MethodCallId = 123;

      TestInitializationContext context = new TestInitializationContext(null, typeof(string).GetMethod("Intern"), new object[0]);

      this.actionDiscoverer.GetInitializationActions(context).Returns(new[] { new InitializationAction("Action1"), new InitializationAction("Action2") });

      this.manager.Initialize(MethodCallId, context);
      Assert.ThrowsDelegate action = () => this.manager.Initialize(MethodCallId, context);

      Assert.Throws<InvalidOperationException>(action);
    }
        /// <summary>
        /// Gets initialization actions.
        /// </summary>
        /// <param name="context">The initialization context.</param>
        /// <returns>List of discovered initialization actions.</returns>
        public sealed override IEnumerable <InitializationAction> GetInitializationActions(object context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            TestInitializationContext initializationContext = context as TestInitializationContext;

            if (initializationContext == null)
            {
                throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Only contexts derived from '{0}' are supported.", typeof(TestInitializationContext).AssemblyQualifiedName));
            }

            return(this.GetInitializationActions(initializationContext));
        }
    public void ShouldDiscoverAndExecuteInitializersInOrderOnInitialization()
    {
      const int MethodCallId = 123;

      TestInitializationContext context = new TestInitializationContext(null, typeof(string).GetMethod("Intern"), new object[0]);

      this.actionDiscoverer.GetInitializationActions(context).Returns(new[] { new InitializationAction("Action1"), new InitializationAction("Action2") });

      this.manager.Initialize(MethodCallId, context);

      Received.InOrder(
        () =>
          {
            this.actionExecutor.ExecuteInitializationForAction(Arg.Is<InitializationAction>(action => action.Id == "Action1"));
            this.actionExecutor.ExecuteInitializationForAction(Arg.Is<InitializationAction>(action => action.Id == "Action2"));
          });
    }
    /// <summary>
    /// Gets initialization actions.
    /// </summary>
    /// <param name="context">The test initialization context.</param>
    /// <returns>List of discovered initialization actions.</returns>
    protected virtual IEnumerable<InitializationAction> GetInitializationActions(TestInitializationContext context)
    {
      if (context == null)
      {
        throw new ArgumentNullException("context");
      }

      List<InitializationHandlerAttribute> attributes = Utility.GetAttributes<InitializationHandlerAttribute>(context.Instance.GetType());
      attributes.AddRange(Utility.GetAttributes<InitializationHandlerAttribute>(context.Method));
      attributes.Sort(InitializationHandlerAttributePriorityComparer.Default);

      List<InitializationAction> result = new List<InitializationAction>();
      foreach (InitializationHandlerAttribute initializationHandlerAttribute in attributes)
      {
        result.Add(Utility.InitializationActionFromInitializationHandlerAttribute(initializationHandlerAttribute, context));
      }

      return result;
    }
    public void ShouldEnumerateAndSubstituteValuesForAppropriateParameters()
    {
      Action<IComparable, IEnumerable, IDisposable> testDelegate = this.TestMethod;
      object[] intactParameter = new object[0];
      object[] arguments = { null, intactParameter, null };
      TestInitializationContext context = new TestInitializationContext(testDelegate.Target, testDelegate.Method, arguments);

      this.provider.SetInitializationContext(context);

      Assert.Equal(5, this.provider.ReceivedCalls().Count());

      this.provider.Received().TestNeedToProvideValue(Arg.Is<object>(obj => obj == null), Arg.Is<ParameterInfo>(parameter => parameter.Position == 0));
      this.provider.Received().TestNeedToProvideValue(Arg.Is<object[]>(obj => obj.Length == 0), Arg.Is<ParameterInfo>(parameter => parameter.Position == 1));
      this.provider.Received().TestNeedToProvideValue(Arg.Is<object>(obj => obj == null), Arg.Is<ParameterInfo>(parameter => parameter.Position == 2));

      this.provider.Received().TestResolveValue(Arg.Is<object>(obj => obj == null), Arg.Is<ParameterInfo>(parameter => parameter.Position == 0));
      this.provider.DidNotReceive().TestResolveValue(Arg.Is<object[]>(obj => obj.Length == 0), Arg.Is<ParameterInfo>(parameter => parameter.Position == 1));
      this.provider.Received().TestResolveValue(Arg.Is<object>(obj => obj == null), Arg.Is<ParameterInfo>(parameter => parameter.Position == 2));
    }
    public void ShouldDiscoverActionsByInitializationHandlerAttributes()
    {
      const string Argument = "argument";

      TestInitializationActionDiscoverer actionDiscoverer = new TestInitializationActionDiscoverer();
      Test test = new Test();

      IEnumerable<InitializationAction> actions = actionDiscoverer.GetInitializationActions(new TestInitializationContext(test, typeof(Test).GetMethod("TestMethod"), new object[] { Argument })).ToArray();

      Assert.Equal(1, actions.Count());

      TestInitializationContext expectedInitializationContext = new TestInitializationContext(test, typeof(Test).GetMethod("TestMethod"), new object[] { Argument });
      
      Assert.Equal(typeof(InitializationHandler1).AssemblyQualifiedName, actions.Single().Id);
      Assert.IsType<InitializationHandler>(actions.Single().State);
      Assert.Equal(typeof(InitializationHandler1), ((InitializationHandler)actions.Single().State).Type);
      Assert.Equal(new object[] { "parameter" }, ((InitializationHandler)actions.Single().State).Arguments);
      Assert.Equal(expectedInitializationContext.Instance, ((TestInitializationContext)actions.Single().Context).Instance);
      Assert.Equal(expectedInitializationContext.Method, ((TestInitializationContext)actions.Single().Context).Method);
      Assert.Equal(expectedInitializationContext.Arguments, ((TestInitializationContext)actions.Single().Context).Arguments);
    }
        /// <summary>
        /// Gets initialization actions.
        /// </summary>
        /// <param name="context">The test initialization context.</param>
        /// <returns>List of discovered initialization actions.</returns>
        protected virtual IEnumerable <InitializationAction> GetInitializationActions(TestInitializationContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            List <InitializationHandlerAttribute> attributes = Utility.GetAttributes <InitializationHandlerAttribute>(context.Instance.GetType());

            attributes.AddRange(Utility.GetAttributes <InitializationHandlerAttribute>(context.Method));
            attributes.Sort(InitializationHandlerAttributePriorityComparer.Default);

            List <InitializationAction> result = new List <InitializationAction>();

            foreach (InitializationHandlerAttribute initializationHandlerAttribute in attributes)
            {
                result.Add(Utility.InitializationActionFromInitializationHandlerAttribute(initializationHandlerAttribute, context));
            }

            return(result);
        }
    public void ShouldSetInitializationContextIfInitializationHandlerImplementsIInitializationContextAware()
    {
      InitializationActionExecutor executor = new InitializationActionExecutor();
      TestInitializationContext context = new TestInitializationContext(null, typeof(string).GetMethod("Intern"), new object[0]);
      InitializationAction action = new InitializationAction("Action") { State = new InitializationHandler(typeof(InitializationContextAwareInitializer), new object[0]), Context = context };

      InitializationContextAwareInitializer.InitializationContext = null;

      executor.ExecuteInitializationForAction(action);

      Assert.Equal(context, InitializationContextAwareInitializer.InitializationContext);
    }