/* Copyright (c) Citrix Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ using System; using System.Reflection; using System.Windows.Forms; using NUnit.Framework; using XenAdmin; namespace XenAdminTests { /// /// A class for exposing private fields of classes. This avoids having to make fields public /// in the production code, therefore maintaining encapsulation while allowing testing. /// /// Look in LicensingTests.LicenseSummaryWrapper for example usage. /// /// The type of the wrapped class. internal abstract class TestWrapper where TClass : class { private readonly TClass _item; protected TestWrapper(TClass item) { Util.ThrowIfParameterNull(item, "item"); _item = item; } protected TestWrapper(IWin32Window window) : this(GetControlFromWindow(window)) { } private static TClass GetControlFromWindow(IWin32Window window) { var control = Control.FromHandle(window.Handle) as TClass; if (control == null) throw new ArgumentException($"window is not a {typeof(TClass).Name} window"); return control; } /// /// Gets the value of the private field from the wrapped class of the specified name. /// /// The type of the field. /// The name of the private field. /// The value of the private field from the wrapped class of the specified name. protected TField GetField(string name) { Util.ThrowIfStringParameterNullOrEmpty(name, "name"); try { return (TField)_item.GetType().GetField(name, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(_item); } catch (Exception e) { Assert.Fail(string.Format("Field {0} of {1} throws {2}.", name, typeof(TClass).Name, e.GetType().Name)); throw; } } /// /// Gets the value of a given private field from the wrapped class's *base* class /// /// The type of the field. /// The name of the field. /// The value of the private field from the base class of the wrapped class of the specified name. protected TField GetBaseClassField(string name) { Util.ThrowIfStringParameterNullOrEmpty(name, "name"); try { Type baseType = _item.GetType().BaseType; Assert.NotNull(baseType, $"{name} is a field of a class that has no base class"); return (TField)baseType.GetField(name, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(_item); } catch (Exception e) { Assert.Fail($"Field {name} of {typeof(TClass).Name} throws {e.GetType().Name}."); throw; } } /// /// Gets the wrapped object. /// public TClass Item { get { return _item; } } /// /// Executes the private method with the specified name from the wrapped class. /// /// The name of the private method. /// The parameters of the private method. protected object ExecuteMethod(string name, object[] parameters) { return _item.GetType().GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic).Invoke(_item, parameters); } /// /// Executes the private method with the specified name from the wrapped class. /// /// The name of the private method. /// The types of the parameters of the private method. /// The parameters of the private method. protected object ExecuteMethod(string name, Type[] types, object[] parameters) { return _item.GetType().GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic, null, types, null).Invoke(_item, parameters); } } }