/// <summary> /// Called as part for the serialization chain. Returns false if it cannot serialize the XML element. /// </summary> public override bool Serialize(XElement node, object obj, ITypeData expectedType) { if (expectedType.IsA(typeof(PackageDependency)) == false) { return(false); } node.Name = "Package"; node.Name = "PackageDependency"; // TODO: remove when server is updated (this is only here for support of the TAP 8.x Repository server that does not yet have a parser that can handle the new name) node.SetAttributeValue("type", null); foreach (var prop in expectedType.GetMembers()) { object val = prop.GetValue(obj); string name = prop.Name; if (val == null) { continue; } if (name == "Name") { name = "Package"; // TODO: remove when server is updated (this is only here for support of the TAP 8.x Repository server that does not yet have a parser that can handle the new name) } node.SetAttributeValue(name, val); } return(true); }
/// <summary> /// Stores an object as a result. These results will be propagated to the ResultStore after the TestStep completes. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="result">The result whose properties should be stored.</param> public void Publish <T>(T result) { if (result == null) { throw new ArgumentNullException("result"); } ITypeData runtimeType = TypeData.GetTypeData(result); if (ResultFunc == null) { lock (resultFuncLock) ResultFunc = new Dictionary <ITypeData, Func <object, ResultTable> >(); } if (!ResultFunc.ContainsKey(runtimeType)) { var Typename = runtimeType.GetDisplayAttribute().GetFullName(); var Props = runtimeType.GetMembers().Where(x => x.Readable && x.TypeDescriptor.DescendsTo(typeof(IConvertible))).ToArray(); var PropNames = Props.Select(p => p.GetDisplayAttribute().GetFullName()).ToArray(); ResultFunc[runtimeType] = (v) => { var cols = new ResultColumn[Props.Length]; for (int i = 0; i < Props.Length; i++) { cols[i] = new ResultColumn(PropNames[i], GetArray(Props[i].TypeDescriptor.AsTypeData().Type, Props[i].GetValue(v))); } return(new ResultTable(Typename, cols)); }; } var res = ResultFunc[runtimeType](result); DoStore(res); }
public IEnumerable <IMemberData> GetMembers() { var names2 = string.Join(",", Object.ExternalParameters.Select(x => x.Name)); if (names == names2 && savedMembers != null) { return(savedMembers); } List <IMemberData> members = new List <IMemberData>(); for (int i = 0; i < Object.ExternalParameters.Length; i++) { var ep = Object.ExternalParameters[i]; members.Add(new ExpandedMemberData(ep, ep.Name) { DeclaringType = this }); } var innerMembers = InnerDescriptor.GetMembers(); foreach (var mem in innerMembers) { members.Add(mem); } savedMembers = members.ToArray(); names = names2; return(members); }
public void SettingOfExternalParametersOnTestReferencePlan() { double defaultValue = 0.7; //seconds double newValue = 7.0; //seconds //double tolerance = Math.Abs(newValue * .0000001); // The tolerance for variation in their delay double values int stepsCount = 20; // how many delay steps should be generated and tested string externalParameterName = "External Delay"; string filePath = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".TapPlan"; GenerateTestPlanWithNDelaySteps(stepsCount, filePath, defaultValue, externalParameterName); try { // Create a test plan TestPlan testPlan = new TestPlan(); // Create a ReferencePlanStep and add it to the test plan TestPlanReference tpr = new TestPlanReference(); MacroString ms = new MacroString(tpr) { Text = filePath }; tpr.Filepath = ms; // automatically calls LoadTesPlan testPlan.ChildTestSteps.Add(tpr); Assert.AreEqual(1, testPlan.ChildTestSteps.Count); Assert.AreEqual(stepsCount, tpr.ChildTestSteps.Count); // ---------------------------------------------------------------------------------------------------- // This is how to get access to a TestPlanReference loaded test plan's children's external paramters: ITypeData ti = TypeData.GetTypeData(tpr); // IMemberInfo mi = ti.GetMember(externalParameterName); <- not possible to get property by its name in case the property name contains characters not valid of a C# property name IMemberData mi = ti.GetMembers().FirstOrDefault(m => m.Attributes.Any(xa => (xa as DisplayAttribute)?.Name == externalParameterName)); // <- the right approach // ---------------------------------------------------------------------------------------------------- Assert.IsNotNull(mi); Assert.AreEqual(defaultValue, mi.GetValue(tpr)); mi.SetValue(tpr, newValue); // Test that the new value has been set on all the inner delay steps for (int i = 0; i < stepsCount; i++) { DelayStep delayStep = tpr.ChildTestSteps[i] as DelayStep; Assert.IsNotNull(delayStep); //Assert.IsTrue(Math.Abs(newValue - delayStep.DelaySecs) <= tolerance); Assert.AreEqual(newValue, delayStep.DelaySecs); } } finally { // delete the temporary file in the end if (File.Exists(filePath)) { File.Delete(filePath); } } }
/// <summary> /// Called as part for the serialization chain. Returns false if it cannot serialize the XML element. /// </summary> public override bool Serialize(XElement node, object obj, ITypeData expectedType) { if (expectedType.IsA(typeof(PackageDef)) == false && expectedType.IsA(typeof(PackageIdentifier)) == false) { return(false); } XNamespace ns = "http://opentap.io/schemas/package"; node.Name = ns + (expectedType.IsA(typeof(PackageIdentifier)) ? nameof(PackageIdentifier) : "Package"); node.SetAttributeValue("type", null); foreach (var prop in expectedType.GetMembers()) { object val = prop.GetValue(obj); if (false == val is string && val is IEnumerable && (val as IEnumerable).GetEnumerator().MoveNext() == false) { continue; // don't write empty enumerables } var defaultAttr = prop.GetAttribute <DefaultValueAttribute>(); if (defaultAttr != null && object.Equals(defaultAttr.Value, val)) { continue; } switch (prop.Name) { case "RawVersion": continue; case "Date": if (((DateTime)val) != DateTime.MinValue) { node.SetAttributeValue("Date", ((DateTime)val).ToString(CultureInfo.InvariantCulture)); } break; case "Description": var mngr = new XmlNamespaceManager(new NameTable()); mngr.AddNamespace("", ns.NamespaceName); // or proper URL var parserContext = new XmlParserContext(null, mngr, null, XmlSpace.None, null); var txtReader = new XmlTextReader($"<Description>{val}</Description>", XmlNodeType.Element, parserContext); var ele = XElement.Load(txtReader); node.Add(ele); break; default: var xmlAttr = prop.GetAttributes <XmlAttributeAttribute>().FirstOrDefault(); if (xmlAttr != null) { string name = prop.Name; if (!String.IsNullOrWhiteSpace(xmlAttr.AttributeName)) { name = xmlAttr.AttributeName; } node.SetAttributeValue(name, val); } else { var elm = new XElement(prop.Name); if (obj != null) { Serializer.Serialize(elm, val, expectedType: prop.TypeDescriptor); } void SetNs(XElement e) { e.Name = ns + e.Name.LocalName; foreach (var n in e.Elements()) { SetNs(n); } } SetNs(elm); node.Add(elm); } break; } } node.SetAttributeValue("xmlns", ns); // ask the TestPlanPackageDependency serializer (the one that writes the // <Package.Dependencies> tag in the bottom of e.g. TestPlan files) to // not write the tag for this file. var depSerializer = Serializer.GetSerializer <TestPlanPackageDependency>(); if (depSerializer != null) { depSerializer.WritePackageDependencies = false; } return(true); }
public void SaveAndLoadTestPlanReference() { double defaultValue = 0.7; //seconds //double tolerance = Math.Abs(newValue * .0000001); // The tolerance for variation in their delay double values int stepsCount = 1; // how many delay steps should be generated and tested string externalParameterName = "External Delay"; string externalParamaterNameEncoded = "External_x0020_Delay"; string externalParamaterNameLegacy = "prop0"; string filePath1 = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".TapPlan"; string filePath2 = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".TapPlan"; string filePath3 = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".TapPlan"; try { // Save the test plan to be referenced GenerateTestPlanWithNDelaySteps(stepsCount, filePath1, defaultValue, externalParameterName); // Scope for separating the test Serialization (Save) from Deserialization (Load) { // Create a test plan TestPlan testPlan = new TestPlan(); // Create a ReferencePlanStep and add it to the test plan TestPlanReference tpr = new TestPlanReference(); MacroString ms = new MacroString(tpr) { Text = filePath1 }; tpr.Filepath = ms; // automatically calls LoadTesPlan testPlan.ChildTestSteps.Add(tpr); // Save the new test plan testPlan.Save(filePath2); // The output should be something like this, remark the "External Delay" has been encoded as "External_x0020_Delay" //<?xml version=\"1.0\" encoding=\"utf-8\"?> //<TestPlan type=\"OpenTap.TestPlan\" Locked=\"false\"> // <Steps> // <TestStep type=\"[email protected]\" Version=\"9.0.0-Development\" Id=\"ae56d9d6-e077-4524-bd14-cb0c9f2d4ced\"> // <External_x0020_Delay>0.7</External_x0020_Delay> // <Filepath>%TEMP%\\e7563ab3-d5e2-4e27-bc77-1f9b76feb37c.TapPlan</Filepath> // <StepMapping /> // <Enabled>true</Enabled> // <Name>Test Plan Reference</Name> // </TestStep> // </Steps> // <Package.Dependencies> // <Package Name=\"OpenTAP\" Version=\"9.0.0+15a61e86\" /> // </Package.Dependencies> //</TestPlan> // Verify that the saved file contains the encoded elements using (var str = File.Open(filePath2, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (var read = new StreamReader(str)) { string content = read.ReadToEnd(); Assert.IsTrue(content.Contains($"<{externalParamaterNameEncoded}>")); Assert.IsTrue(content.Contains($"</{externalParamaterNameEncoded}>")); Assert.IsFalse(content.Contains($"<{externalParameterName}>")); Assert.IsFalse(content.Contains($"</{externalParameterName}>")); Assert.IsFalse(content.Contains($"<{externalParamaterNameLegacy}>")); Assert.IsFalse(content.Contains($"</{externalParamaterNameLegacy}>")); } } } // Scope for separating the test Deserialization (Load) from Serialization (Save) { TestPlan testPlan = TestPlan.Load(filePath2); Assert.AreEqual(1, testPlan.ChildTestSteps.Count); TestPlanReference tpr = testPlan.ChildTestSteps[0] as TestPlanReference; Assert.IsNotNull(tpr); ITypeData ti = TypeData.GetTypeData(tpr); // ensure there is a property "External Delay" IMemberData mi = ti.GetMembers().FirstOrDefault(m => m.Attributes.Any(xa => (xa as DisplayAttribute)?.Name == externalParameterName)); Assert.IsNotNull(mi); Assert.AreEqual(defaultValue, mi.GetValue(tpr)); // ensure there is no property "External_x0020_Delay" Assert.IsNull(ti.GetMembers().FirstOrDefault(m => m.Attributes.Any(xa => (xa as DisplayAttribute)?.Name == externalParamaterNameEncoded))); // ensure there is no property "prop0" Assert.IsNull(ti.GetMembers().FirstOrDefault(m => m.Attributes.Any(xa => (xa as DisplayAttribute)?.Name == externalParamaterNameLegacy))); } // Scope for separating the test Deserialization legacy (Load) from Serialization (Save) { // Replace string content = ""; using (var str = File.Open(filePath2, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (var read = new StreamReader(str)) { content = read.ReadToEnd(); } } Assert.IsTrue(content.Contains($"<{externalParamaterNameEncoded}>")); Assert.IsTrue(content.Contains($"</{externalParamaterNameEncoded}>")); Assert.IsFalse(content.Contains($"<{externalParameterName}>")); Assert.IsFalse(content.Contains($"</{externalParameterName}>")); Assert.IsFalse(content.Contains($"<{externalParamaterNameLegacy}>")); Assert.IsFalse(content.Contains($"</{externalParamaterNameLegacy}>")); content = content.Replace(externalParamaterNameEncoded, externalParamaterNameLegacy); Assert.IsFalse(content.Contains($"<{externalParamaterNameEncoded}>")); Assert.IsFalse(content.Contains($"</{externalParamaterNameEncoded}>")); Assert.IsFalse(content.Contains($"<{externalParameterName}>")); Assert.IsFalse(content.Contains($"</{externalParameterName}>")); Assert.IsTrue(content.Contains($"<{externalParamaterNameLegacy}>")); Assert.IsTrue(content.Contains($"</{externalParamaterNameLegacy}>")); Assert.IsFalse(File.Exists(filePath3)); using (var str = File.Open(filePath3, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) { using (var write = new StreamWriter(str)) { write.Write(content); } } Assert.IsTrue(File.Exists(filePath3)); // Load the test case and its test ref TestPlan testPlan = TestPlan.Load(filePath3); Assert.AreEqual(1, testPlan.ChildTestSteps.Count); TestPlanReference tpr = testPlan.ChildTestSteps[0] as TestPlanReference; Assert.IsNotNull(tpr); ITypeData ti = TypeData.GetTypeData(tpr); // ensure there is a property "External Delay" IMemberData mi = ti.GetMembers().FirstOrDefault(m => m.Attributes.Any(xa => (xa as DisplayAttribute)?.Name == externalParameterName)); Assert.IsNotNull(mi); Assert.AreEqual(defaultValue, mi.GetValue(tpr)); // ensure there is no property "External_x0020_Delay" Assert.IsNull(ti.GetMembers().FirstOrDefault(m => m.Attributes.Any(xa => (xa as DisplayAttribute)?.Name == externalParamaterNameEncoded))); // ensure there is no property "prop0" Assert.IsNull(ti.GetMembers().FirstOrDefault(m => m.Attributes.Any(xa => (xa as DisplayAttribute)?.Name == externalParamaterNameLegacy))); } } finally { if (File.Exists(filePath1)) { File.Delete(filePath1); } if (File.Exists(filePath2)) { File.Delete(filePath2); } if (File.Exists(filePath3)) { File.Delete(filePath3); } } }
public IEnumerable <IMemberData> GetMembers() { return(innerType.GetMembers().Concat(members)); }
public override bool Serialize(XElement node, object obj, ITypeData expectedType) { if (expectedType.IsA(typeof(PackageFile)) == false) { return(false); } foreach (IMemberData prop in expectedType.GetMembers().Where(s => !s.HasAttribute <XmlIgnoreAttribute>())) { object val = prop.GetValue(obj); string name = prop.Name; var defaultValueAttr = prop.GetAttribute <DefaultValueAttribute>(); if (defaultValueAttr != null) { if (Object.Equals(defaultValueAttr.Value, val)) { continue; } if (defaultValueAttr.Value == null) { var enu = val as IEnumerable; if (enu != null && enu.GetEnumerator().MoveNext() == false) // the value is an empty IEnumerable { continue; // We take an empty IEnumerable to be the same as null } } } if (name == "RelativeDestinationPath") { name = "Path"; } if (name == "DoObfuscate") { name = "Obfuscate"; } if (name == "Plugins") { XElement plugins = new XElement("Plugins"); Serializer.Serialize(plugins, val, prop.TypeDescriptor); node.Add(plugins); continue; } if (name == "IgnoredDependencies") { if (val is List <string> igDeps) { foreach (string igDep in igDeps) { node.Add(new XElement("IgnoreDependency") { Value = igDep }); } continue; } } if (name == "CustomData") { if (val is List <ICustomPackageData> packageActions) { foreach (ICustomPackageData action in packageActions) { if (action is MissingPackageData) { continue; } XElement xAction = new XElement(action.GetType().GetDisplayAttribute().Name); Serializer.Serialize(xAction, action, TypeData.GetTypeData(action)); node.Add(xAction); } } continue; } node.SetAttributeValue(name, val); } return(true); }