Use extra class for xml exception

Add handler class for xml errors
Fix testcases
This commit is contained in:
Flamefire committed 2014-11-17 19:27:43 +01:00
1 parent a2aafd4614
commit 33618b4c97
12 files changed
+334 -71

No files matched your search

+15 -1
View File
@@ -43,9 +43,12 @@ namespace Vocaluxe.Base
// ReSharper disable UnassignedField.Global
#pragma warning disable 649
// ReSharper disable MemberCanBePrivate.Global
public struct SConfigInfo
// ReSharper restore MemberCanBePrivate.Global
{
// ReSharper disable NotAccessedField.Global
// ReSharper disable NotAccessedField.Local
public string Version;
public string Time;
public string Platform;
@@ -54,6 +57,7 @@ namespace Vocaluxe.Base
public int Screens;
public string PrimaryScreenResolution;
public string Directory;
// ReSharper restore NotAccessedField.Local
// ReSharper restore NotAccessedField.Global
}
@@ -248,10 +252,20 @@ namespace Vocaluxe.Base
_Initialized = true;
}
private static bool _XmlErrorsOccured;
private static void _HandleXmlError(CXmlException e)
{
_XmlErrorsOccured = true;
}
private static void _LoadConfig()
{
var xml = new CXmlDeserializer();
_XmlErrorsOccured = false;
var xml = new CXmlDeserializer(new CXmlErrorHandler(_HandleXmlError));
Config = xml.Deserialize<SConfig>(_FileConfig);
if (_XmlErrorsOccured)
CLog.LogError("There were some warnings or errors loading the config file. Some values might have been reset to their defaults.");
if (Config.Game.SongFolder.Length > 0)
{
+2 -3
View File
@@ -21,7 +21,6 @@ using System.Drawing;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Linq;
using VocaluxeLib;
using VocaluxeLib.Draw;
@@ -179,9 +178,9 @@ namespace Vocaluxe.Base
{
theme = xml.Deserialize<SThemeCover>(Path.Combine(folderPath, file));
}
catch (XmlException e)
catch (CXmlException e)
{
CLog.LogError("Error loading cover theme " + file + ": " + e.Message);
CLog.LogError("Error loading cover theme " + file + ": " + e);
continue;
}
-1
View File
@@ -19,7 +19,6 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Xml;
using Vocaluxe.Base.Fonts;
using Vocaluxe.Base.ThemeSystem;
using VocaluxeLib;
+2 -3
View File
@@ -19,7 +19,6 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib;
using VocaluxeLib.Draw;
@@ -98,9 +97,9 @@ namespace Vocaluxe.Base.ThemeSystem
{
_Required = xml.Deserialize<SRequiredElements>(path);
}
catch (XmlException e)
catch (CXmlException e)
{
CLog.LogError("Error reading required elements: " + e.Message);
CLog.LogError("Error reading required elements: " + e);
return false;
}
for (int i = 1; i <= CSettings.MaxNumPlayer; i++)
+1 -1
View File
@@ -51,4 +51,4 @@ using System.Runtime.InteropServices;
[assembly: AssemblyVersion("0.3.0.83")]
[assembly: AssemblyFileVersion("0.3.0.83")]
[assembly: AssemblyInformationalVersion("GITVERSION")]
[assembly: AssemblyInformationalVersion("GITVERSION")]
-1
View File
@@ -19,7 +19,6 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Xml;
using VocaluxeLib.Draw;
using VocaluxeLib.Game;
using VocaluxeLib.Menu;
+1 -2
View File
@@ -18,7 +18,6 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib.Xml;
@@ -116,7 +115,7 @@ namespace VocaluxeLib.Profile
}
catch (Exception e2)
{
if (!(e2 is XmlException))
if (!(e2 is CXmlException))
e = e2;
return false;
}
+22 -5
View File
@@ -44,7 +44,9 @@ namespace VocaluxeLib.Xml
/// Attribute for float fields to enforce normalized (0&lt;=x&lt;=1) values
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class XmlNormalizedAttribute : Attribute {}
public class XmlNormalizedAttribute : XmlRangedAttribute {
public XmlNormalizedAttribute() : base(0, 1) {}
}
/// <summary>
/// Attribute for int fields to enforce values in the given range
@@ -60,6 +62,23 @@ namespace VocaluxeLib.Xml
Min = min;
Max = max;
}
public bool IsValid(Type type, object value)
{
if (type == typeof(int))
return ((int)value).IsInRange(Min, Max);
if (type == typeof(float))
return ((float)value).IsInRange(Min, Max);
if (type == typeof(double))
return ((double)value).IsInRange(Min, Max);
Debug.Assert(false, "Ranged attribute has invalid type");
return false;
}
public override string ToString()
{
return Min + "-" + Max;
}
}
// ReSharper restore InconsistentNaming
@@ -153,12 +172,10 @@ namespace VocaluxeLib.Xml
}
if (field.HasAttribute<XmlNormalizedAttribute>())
{
Debug.Assert(info.Type == typeof(float) || (info.IsNullable && info.SubType == typeof(float)), "Only floats can be normalized");
info.IsNormalized = true;
}
info.Ranged = field.GetAttribute<XmlRangedAttribute>();
Debug.Assert(info.Ranged == null || info.Type == typeof(int) || info.Type == typeof(float) || info.Type == typeof(double),
Type tmpType = info.IsNullable ? info.SubType : info.Type;
Debug.Assert(info.Ranged == null || tmpType == typeof(int) || tmpType == typeof(float) || tmpType == typeof(double),
"Only ints,floats and double can be ranged");
DefaultValueAttribute defAttr = field.GetAttribute<DefaultValueAttribute>();
+156 -45
View File
@@ -18,7 +18,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -28,7 +27,7 @@ using System.Xml;
namespace VocaluxeLib.Xml
{
public class CXmlDeserializer
public class CXmlException : Exception
{
#region Debug Helpers
/// <summary>
@@ -87,13 +86,105 @@ namespace VocaluxeLib.Xml
}
#endregion Debug Helpers
private readonly XmlNode _Node;
public readonly bool IsError;
public CXmlException(string msg, XmlNode node, bool isError = true)
: base(msg)
{
IsError = isError;
_Node = node;
}
public override string Message
{
get { return ToString(); }
}
public override String ToString()
{
string xPath = _Node == null ? "" : _GetXPath(_Node);
string type = IsError ? "Error" : "Warning";
return type + ": " + base.Message.Replace("%n", xPath);
}
}
public class CXmlInvalidValueException : CXmlException
{
private readonly string _Value;
public CXmlInvalidValueException(string msg, XmlNode node, string value, bool isError = true) : base(msg, node, isError)
{
_Value = value;
}
public override String ToString()
{
return base.ToString().Replace("%v", _Value);
}
}
public interface IXmlErrorHandler
{
/// <summary>
/// Gets called for every error that occurs during xml reading.
/// Recommended way of handling is throwing that error and log it<br />
/// However if the function returns without throwing a fallback solution is applied to continue reading where possible e.g. by using default values or ignoring the element
/// </summary>
/// <param name="e">Error that would be thrown</param>
void HandleError(CXmlException e);
}
/// <summary>
/// Class for simple construction of error handlers by using a delegate
/// </summary>
public class CXmlErrorHandler : IXmlErrorHandler
{
public delegate void HandleErrorDelegate(CXmlException e);
private readonly HandleErrorDelegate _HandleError;
public CXmlErrorHandler(HandleErrorDelegate handleError)
{
_HandleError = handleError;
}
public void HandleError(CXmlException e)
{
_HandleError(e);
}
}
public class CXmlDeserializer
{
private class CXmlDefaultErrorHandler : IXmlErrorHandler
{
public void HandleError(CXmlException e)
{
if (e.IsError)
throw e;
CBase.Log.LogError(e.ToString());
}
}
private readonly IXmlErrorHandler _ErrorHandler;
/// <summary>
/// Creates a new XmlDeserializer
/// </summary>
/// <param name="errorHandler">Class to be used for error callbacks, if not given a default handler will be used which throws errors and logs warnings</param>
public CXmlDeserializer(IXmlErrorHandler errorHandler = null)
{
_ErrorHandler = errorHandler ?? new CXmlDefaultErrorHandler();
}
/// <summary>
/// Returns the value if the given node
/// </summary>
/// <param name="node">Node to process</param>
/// <param name="type">Type of the object at that node</param>
/// <param name="subName">Name of the sub nodes for array types(Array,List,Dictionary), can be set by XmlArrayItemAttribute and defaults to the type name</param>
/// <param name="value">If given, no new class is created and value is used instead</param>
/// <param name="value">If given, no new class is created and value is used instead, also used as default value</param>
/// <returns></returns>
private object _GetValue(XmlNode node, Type type, string subName = null, object value = null)
{
@@ -106,13 +197,14 @@ namespace VocaluxeLib.Xml
}
catch (Exception)
{
throw new XmlException("Invalid value in " + _GetXPath(node));
_ErrorHandler.HandleError(new CXmlInvalidValueException("Invalid value '%v' in %n", node, stringValue));
return value;
}
}
if (type == typeof(string))
return node.InnerText;
if (type.IsPrimitive)
return _GetPrimitiveValue(node, type);
return _GetPrimitiveValue(node, type) ?? value;
if (type.IsNullable())
{
if (!node.HasChildNodes)
@@ -132,9 +224,10 @@ namespace VocaluxeLib.Xml
if (subNode is XmlComment)
continue;
if (subName == subNode.Name.ToLowerInvariant() && !subNode.Name.ToLowerInvariant().StartsWith(subName))
throw new XmlException("Invalid list entry '" + subNode.Name + "' in " + _GetXPath(node) + "; Expected: " + subName);
_ErrorHandler.HandleError(new CXmlException("Invalid list entry '" + subNode.Name + "' in %n; Expected: " + subName, node));
object subValue = _GetValue(subNode, subType);
subValues.Add(subValue);
if (subValue != null)
subValues.Add(subValue);
}
if (value == null)
return _CreateList(type, subValues);
@@ -152,22 +245,24 @@ namespace VocaluxeLib.Xml
{
if (subNode is XmlComment)
continue;
object subValue = _GetValue(subNode, subType);
string key;
if (subName != null)
{
if (subName != subNode.Name.ToLowerInvariant() && !subNode.Name.ToLowerInvariant().StartsWith(subName))
throw new XmlException("Invalid dictionary entry '" + subNode.Name + "' in " + _GetXPath(node) + "; Expected: " + subName);
if (subNode.Attributes == null)
throw new XmlException("'name' attribute is missing in " + _GetXPath(subNode));
XmlNode nameAtt = subNode.Attributes.GetNamedItem("name");
_ErrorHandler.HandleError(new CXmlException("Invalid dictionary entry '" + subNode.Name + "' in %n; Expected: " + subName, node));
XmlNode nameAtt = (subNode.Attributes == null) ? null : subNode.Attributes.GetNamedItem("name");
if (nameAtt == null)
throw new XmlException("'name' attribute is missing in " + _GetXPath(subNode));
{
_ErrorHandler.HandleError(new CXmlException("'name' attribute is missing in %n", subNode));
continue;
}
key = nameAtt.Value;
}
else
key = subNode.Name;
add.Invoke(dict, new object[] {key, subValue});
object subValue = _GetValue(subNode, subType);
if (subValue != null)
add.Invoke(dict, new object[] {key, subValue});
}
return dict;
}
@@ -180,7 +275,8 @@ namespace VocaluxeLib.Xml
}
catch (Exception)
{
throw new XmlException("Could not create instance of " + _GetXPath(node) + "(Type=" + type.Name + ")");
_ErrorHandler.HandleError(new CXmlException("Could not create instance of %n(Type=" + type.Name + ")", node));
return null;
}
}
_ReadChildNodes(node, value, true);
@@ -203,7 +299,7 @@ namespace VocaluxeLib.Xml
int p = nodeVal.IndexOf(',');
if (p > 0 && p >= nodeVal.Length - 3)
{
CBase.Log.LogError("German number format converted to english in " + _GetXPath(node));
_ErrorHandler.HandleError(new CXmlInvalidValueException("German number format converted to English in %n", node, nodeVal, false));
char[] tmp = nodeVal.ToCharArray();
tmp[p] = '.';
nodeVal = new string(tmp);
@@ -212,11 +308,13 @@ namespace VocaluxeLib.Xml
}
catch (FormatException e)
{
throw new XmlException("Invalid format in " + _GetXPath(node) + ": '" + nodeVal + "' (" + e.Message + ")");
_ErrorHandler.HandleError(new CXmlInvalidValueException("Invalid format in %n: '%v' (" + e.Message + ")", node, nodeVal));
return null;
}
catch (InvalidCastException e)
{
throw new XmlException(e.Message + " in " + _GetXPath(node) + ": '" + nodeVal + "'");
_ErrorHandler.HandleError(new CXmlInvalidValueException(e.Message + " in %n: '%v'", node, nodeVal));
return null;
}
return value;
}
@@ -324,16 +422,29 @@ namespace VocaluxeLib.Xml
}
if (curField >= fields.Count)
{
string msg = "Unexpected element: " + _GetXPath(node);
string msg = "Unexpected element: %n";
if (fields.Count > 0)
msg += " Expected: " + string.Join(", ", fields.Select(f => f.Name));
throw new XmlException(msg);
_ErrorHandler.HandleError(new CXmlException(msg, node));
continue;
}
if (field.IsByteArray)
{
field.SetValue(o, Convert.FromBase64String(node.InnerText));
fields.RemoveAt(curField);
fields.RemoveAt(curField); //Do this also on error
byte[] value;
try
{
value = Convert.FromBase64String(node.InnerText);
}
catch (Exception)
{
_ErrorHandler.HandleError(new CXmlInvalidValueException("Invalid value in %n: %v", node, node.InnerText));
if (!_CheckAndSetDefaultValue(o, field))
_ErrorHandler.HandleError(new CXmlException("No default value for %n", node));
continue;
}
field.SetValue(o, value);
}
else if (field.IsEmbeddedList)
{
@@ -344,36 +455,30 @@ namespace VocaluxeLib.Xml
embLists.Add(field.Name, entry);
}
object subValue = _GetValue(node, field.SubType);
entry.Item2.Add(subValue);
if (subValue != null)
entry.Item2.Add(subValue);
}
else
{
fields.RemoveAt(curField); //Do this also on error
object value = _GetValue(node, field.Type, field.ArrayItemName);
if (field.IsNormalized)
if (value == null)
{
if (field.IsNullable && !((float?)value).Value.IsInRange(0, 1) ||
!field.IsNullable && !((float)value).IsInRange(0, 1))
throw new XmlException("Value in " + _GetXPath(node) + " is not normalized. (Value=" + value + ")");
}
if (field.Ranged != null && value != null)
{
bool ok = false;
if (field.Type == typeof(int))
ok = ((int)value).IsInRange(field.Ranged.Min, field.Ranged.Max);
else if (field.Type == typeof(float))
ok = ((float)value).IsInRange(field.Ranged.Min, field.Ranged.Max);
else if (field.Type == typeof(double))
ok = ((double)value).IsInRange(field.Ranged.Min, field.Ranged.Max);
else
Debug.Assert(false, "Ranged attribute has invalid type");
if (!ok)
if (_CheckAndSetDefaultValue(o, field))
continue;
if (!field.IsNullable)
{
throw new XmlException("Value in " + _GetXPath(node) + " is not in the range " + field.Ranged.Min + "-" + field.Ranged.Max + ". (Value=" + value +
")");
_ErrorHandler.HandleError(new CXmlException("No default value for unset field at %n", node));
continue;
}
}
if (field.Ranged != null && value != null && !field.Ranged.IsValid(field.IsNullable ? field.SubType : field.Type, value))
{
_ErrorHandler.HandleError(new CXmlInvalidValueException("Value in %n is not in the range " + field.Ranged +
". (Value=%v)", node, value.ToString()));
}
field.SetValue(o, value);
fields.RemoveAt(curField);
}
}
//Add embedded lists
@@ -386,7 +491,7 @@ namespace VocaluxeLib.Xml
foreach (SFieldInfo field in fields)
{
if (!_CheckAndSetDefaultValue(o, field))
throw new XmlException("element: " + field.Name + " is missing in " + _GetXPath(parent));
_ErrorHandler.HandleError(new CXmlException("element: " + field.Name + " is missing in %n", parent));
}
}
@@ -400,12 +505,18 @@ namespace VocaluxeLib.Xml
private T _Deserialize<T>(XmlReader reader, object o) where T : new()
{
if (reader.IsEmptyElement)
{
_ErrorHandler.HandleError(new CXmlException("No content in xml!", null));
return (T)o;
}
XmlDocument xDoc = new XmlDocument();
xDoc.Load(reader);
if (xDoc.DocumentElement == null)
throw new XmlException("No root element found!");
{
_ErrorHandler.HandleError(new CXmlException("Root element not found!", null));
return (T)o;
}
try
{
o = _GetValue(xDoc.DocumentElement, o.GetType(), o.GetType().GetSubTypeName(), o);
+93
View File
@@ -0,0 +1,93 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Reflection;
namespace VocaluxeLib.Xml
{
public struct SFieldInfo
{
private readonly FieldInfo _Field;
private readonly PropertyInfo _Property;
public Type Type
{
get { return _Field != null ? _Field.FieldType : _Property.PropertyType; }
}
public string Name;
public string AltName;
public object DefaultValue;
public bool HasDefaultValue;
public bool IsAttribute;
/// <summary>
/// List with child elements (
/// <List>
/// <El /><El />
/// </List>
/// )
/// </summary>
public bool IsList;
/// <summary>
/// List w/o child elements(<List /><List />)
/// </summary>
public bool IsEmbeddedList;
/// <summary>
/// List where the element names are the keys
/// </summary>
public bool IsDictionary;
/// <summary>
/// Byte arrays w/o XmlArrayAttribute are serialized as Base64-Encoded strings
/// </summary>
public bool IsByteArray;
public bool IsNullable;
public XmlRangedAttribute Ranged;
/// <summary>
/// Type of subnodes (array/list elements or dictionary values)
/// </summary>
public Type SubType;
/// <summary>
/// Name of the subnodes
/// </summary>
public string ArrayItemName;
public SFieldInfo(FieldInfo field)
: this()
{
_Field = field;
}
public SFieldInfo(PropertyInfo property)
: this()
{
_Property = property;
}
public void SetValue(object o, object value)
{
if (_Field != null)
_Field.SetValue(o, value);
else
_Property.SetValue(o, value, new object[] {});
}
public object GetValue(object o)
{
return (_Field != null) ? _Field.GetValue(o) : _Property.GetValue(o, new object[] {});
}
}
}
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="language">Deutsch</string>
<string name="TR_PROGRAM_NAME">Vocaluxe</string>
<string name="TR_GENERAL_AND">und</string>
<string name="TR_BUTTON_EXIT">Exit</string>
<string name="TR_BUTTON_SAVE">Speichern</string>
<string name="TR_BUTTON_BACK">Zurück</string>
<string name="TR_BUTTON_START">Start</string>
<string name="TR_DEBUG_AUDIO_STREAMS">Audio-Streams</string>
<string name="TR_DEBUG_VIDEO_STREAMS">Video-Streams</string>
<string name="TR_DEBUG_TEXTURES">Textures</string>
<string name="TR_DEBUG_TONE_ABS">ToneAbs</string>
<string name="TR_DEBUG_MAX_VOLUME">Max. Volume</string>
<string name="TR_DEBUG_SONGS">Geladene Songs</string>
<string name="TR_DEBUG_MOUSE">Maus</string>
<string name="TR_DEBUG_MEMORY">Speicherverbrauch</string>
<string name="TR_GAMEMODE_NORMAL">Normal</string>
<string name="TR_GAMEMODE_DUET">Duett</string>
<string name="TR_GAMEMODE_MEDLEY">Medley</string>
<string name="TR_GAMEMODE_SHORTSONG">Kurz-Version</string>
<string name="TR_RATING_VOCAL_HERO">Vocal Hero</string>
<string name="TR_RATING_SUPERSTAR">Superstar</string>
<string name="TR_RATING_LEAD_SINGER">Hit-Künstler</string>
<string name="TR_RATING_RISING_STAR">Sternchen</string>
<string name="TR_RATING_HOPEFUL">Fortgeschritten</string>
<string name="TR_RATING_WANNABE">Möchtegern</string>
<string name="TR_RATING_AMATEUR">Amateur</string>
<string name="TR_RATING_TONE_DEAF">Nichtskönner</string>
<string name="TR_USERROLE_GUEST">Gast</string>
<string name="TR_USERROLE_NORMAL">Normaler Benutzer</string>
<string name="TR_USERROLE_ADMIN">Administrator</string>
<string name="TR_USERROLE_KEYBOARDUSER">Tastatur</string>
</resources>
+8 -9
View File
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Vocaluxe.Base;
@@ -167,7 +166,7 @@ namespace VocaluxeTests
foreach (string s1 in s)
{
string sTmp = s1;
_AssertFail<SBasic, XmlException>(sTmp);
_AssertFail<SBasic, CXmlException>(sTmp);
}
}
@@ -196,7 +195,7 @@ namespace VocaluxeTests
foreach (string s1 in s)
{
string sTmp = s1;
_AssertFail<SBasic, XmlException>(sTmp);
_AssertFail<SBasic, CXmlException>(sTmp);
}
}
@@ -253,7 +252,7 @@ namespace VocaluxeTests
_AssertSerDeserMatch<SList>(_XMLList[2]);
res = ser.Serialize(foo);
Assert.AreEqual(_XMLList[2], res, "Serialization2 failed");
_AssertFail<SList, XmlException>(_Empty);
_AssertFail<SList, CXmlException>(_Empty);
}
[TestMethod]
@@ -275,7 +274,7 @@ namespace VocaluxeTests
Assert.AreEqual(foo.Ints.Length, 0, "Deserialization2 failed");
res = ser.Serialize(foo);
Assert.AreEqual(_XMLList[2], res, "Serialization2 failed");
_AssertFail<SArray, XmlException>(_Empty);
_AssertFail<SArray, CXmlException>(_Empty);
}
private const string _XMLListEmb = _Head + @"<root>
@@ -319,7 +318,7 @@ namespace VocaluxeTests
Assert.AreEqual(foo.Ints.Count, 0, "Deserialization failed");
res = ser.Serialize(foo);
Assert.AreEqual(_XMLListEmb3, res, "Serialization failed");
_AssertFail<SListEmb, XmlException>(_Empty);
_AssertFail<SListEmb, CXmlException>(_Empty);
}
[TestMethod]
@@ -341,7 +340,7 @@ namespace VocaluxeTests
Assert.AreEqual(foo.Ints.Length, 0, "Deserialization failed");
res = ser.Serialize(foo);
Assert.AreEqual(_XMLListEmb3, res, "Serialization failed");
_AssertFail<SArrayEmb, XmlException>(_Empty);
_AssertFail<SArrayEmb, CXmlException>(_Empty);
}
[TestMethod]
@@ -377,7 +376,7 @@ namespace VocaluxeTests
public void TestIgnore()
{
_AssertSerDeserMatch<SIgnore>(_XmlIgnore);
_AssertFail<SIgnore, XmlException>(_XmlIgnore2);
_AssertFail<SIgnore, CXmlException>(_XmlIgnore2);
}
[TestMethod]
@@ -438,7 +437,7 @@ namespace VocaluxeTests
}
Assert.IsInstanceOfType(foo, type, "Wrong type with " + type.Name);
var ser = new CXmlSerializer(type == typeof(CConfig.SConfig));
string newXml = ser.Serialize(type == typeof(Dictionary<string, string>) ? "resources" : foo);
string newXml = ser.Serialize(foo, type == typeof(Dictionary<string, string>) ? "resources" : null);
// Typename will be uppercase but input is lowercase
newXml = newXml.Replace("<String", "<string").Replace("</String", "</string");
string oldXml = File.ReadAllText(xmlPath);