﻿#region Apache License
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to you under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

// https://github.com/nunit/nunit-csharp-samples/blob/master/ExpectedExceptionExample/ExpectedExceptionAttribute.cs

using System;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands;

namespace NUnit.Framework
{
	/// <summary>
	/// A simple ExpectedExceptionAttribute
	/// </summary>
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	public class ExpectedExceptionAttribute : NUnitAttribute, IWrapTestMethod
	{
		private readonly Type _expectedExceptionType;

		public ExpectedExceptionAttribute(Type type)
		{
			_expectedExceptionType = type;
		}

		public TestCommand Wrap(TestCommand command)
		{
			return new ExpectedExceptionCommand(command, _expectedExceptionType);
		}

		private class ExpectedExceptionCommand : DelegatingTestCommand
		{
			private readonly Type _expectedType;

			public ExpectedExceptionCommand(TestCommand innerCommand, Type expectedType)
				: base(innerCommand)
			{
				_expectedType = expectedType;
			}

			public override TestResult Execute(TestExecutionContext context)
			{
				Type caughtType = null;

				try
				{
					innerCommand.Execute(context);
				}
				catch (Exception ex)
				{
					if (ex is NUnitException)
						ex = ex.InnerException;
					caughtType = ex.GetType();
				}

				if (caughtType == _expectedType)
					context.CurrentResult.SetResult(ResultState.Success);
				else if (caughtType != null)
					context.CurrentResult.SetResult(ResultState.Failure,
						string.Format("Expected {0} but got {1}", _expectedType.Name, caughtType.Name));
				else
					context.CurrentResult.SetResult(ResultState.Failure,
						string.Format("Expected {0} but no exception was thrown", _expectedType.Name));

				return context.CurrentResult;
			}
		}
	}
}
