diff --git a/.gitignore b/.gitignore
index bb7e9bd0..4b8d2072 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,3 +55,5 @@ Thumbs.db
/Installer/Prerequisites/GStreamer x86/gstreamer-1.0-x86-1.4.1.msi
/WebserverInitalConfig/bin
/PhoneGap/
+/TestResults
+/VocaluxeTests/bin
diff --git a/Vocaluxe.sln b/Vocaluxe.sln
index fb446cb0..b3499d21 100644
--- a/Vocaluxe.sln
+++ b/Vocaluxe.sln
@@ -25,6 +25,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebserverInitalConfig", "We
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PitchTracker", "PitchTracker\PitchTracker.vcxproj", "{54A48AF7-515C-4EDD-B395-2BFFA096050A}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VocaluxeTests", "VocaluxeTests\VocaluxeTests.csproj", "{93356718-3A0B-4784-AAE1-215065BFFC66}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2BDDF9CE-271F-49C6-A92E-9CB6185ACF58}"
+ ProjectSection(SolutionItems) = preProject
+ Vocaluxe.testsettings = Vocaluxe.testsettings
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
DebugLinux|x64 = DebugLinux|x64
@@ -195,6 +202,26 @@ Global
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|x64.Build.0 = Release|x64
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|x86.ActiveCfg = Release|Win32
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|x86.Build.0 = Release|Win32
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.DebugLinux|x64.ActiveCfg = Debug|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.DebugLinux|x64.Build.0 = Debug|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.DebugLinux|x86.ActiveCfg = Debug|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.DebugLinux|x86.Build.0 = Debug|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.DebugWin|x64.ActiveCfg = Debug|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.DebugWin|x64.Build.0 = Debug|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.DebugWin|x86.ActiveCfg = Debug|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.DebugWin|x86.Build.0 = Debug|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.InstallerWin|x64.ActiveCfg = Release|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.InstallerWin|x64.Build.0 = Release|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.InstallerWin|x86.ActiveCfg = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.InstallerWin|x86.Build.0 = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseLinux|x64.ActiveCfg = Release|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseLinux|x64.Build.0 = Release|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseLinux|x86.ActiveCfg = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseLinux|x86.Build.0 = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseWin|x64.ActiveCfg = Release|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseWin|x64.Build.0 = Release|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseWin|x86.ActiveCfg = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseWin|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Vocaluxe.sln.DotSettings b/Vocaluxe.sln.DotSettings
index 661e1a2c..9330a5ef 100644
--- a/Vocaluxe.sln.DotSettings
+++ b/Vocaluxe.sln.DotSettings
@@ -114,4 +114,9 @@ along with $SOLUTION$. If not, see <http://www.gnu.org/licenses/>.<Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Private, Protected, ProtectedInternal, Internal, Public" Description="Classes"><ElementKinds><Kind Name="CLASS" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="C" Suffix="" Style="AaBb" /></Policy>
<Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Private, Protected" Description="Fields (not public)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /><Kind Name="METHOD" /><Kind Name="PROPERTY" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="AaBb" /></Policy>
<Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Private, Protected, ProtectedInternal, Internal, Public" Description="Structs"><ElementKinds><Kind Name="STRUCT" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="S" Suffix="" Style="AaBb" /></Policy>
+ False
+ Vocaluxe.testsettings
+ True
+ False
+ True
\ No newline at end of file
diff --git a/Vocaluxe.testsettings b/Vocaluxe.testsettings
new file mode 100644
index 00000000..ccf7a8c8
--- /dev/null
+++ b/Vocaluxe.testsettings
@@ -0,0 +1,28 @@
+
+
+ Dies sind die standardmäßigen Testeinstellungen für einen lokalen Testlauf.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Vocaluxe/Program.cs b/Vocaluxe/Program.cs
index a00fbba6..5e1fb26c 100644
--- a/Vocaluxe/Program.cs
+++ b/Vocaluxe/Program.cs
@@ -20,6 +20,7 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
+using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Windows.Forms;
@@ -28,6 +29,8 @@ using Vocaluxe.Base.Fonts;
using Vocaluxe.Base.Server;
using Vocaluxe.Base.ThemeSystem;
+[assembly: InternalsVisibleTo("VocaluxeTests")]
+
namespace Vocaluxe
{
class CLoadingException : Exception
diff --git a/VocaluxeTests/Properties/AssemblyInfo.cs b/VocaluxeTests/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..5f2bcc95
--- /dev/null
+++ b/VocaluxeTests/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über folgende
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("VocaluxeTests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("VocaluxeTests")]
+[assembly: AssemblyCopyright("Copyright © 2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Wenn ComVisible auf "false" festgelegt wird, sind die Typen innerhalb dieser Assembly
+// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("3bdc6da5-a651-452e-903c-deec310288ad")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
+// durch Einsatz von '*', wie in nachfolgendem Beispiel:
+// [Assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/VocaluxeTests/TestXmlFiles/SConfig.xml b/VocaluxeTests/TestXmlFiles/SConfig.xml
new file mode 100644
index 00000000..c2258062
--- /dev/null
+++ b/VocaluxeTests/TestXmlFiles/SConfig.xml
@@ -0,0 +1,97 @@
+
+
+
+
+ TR_CONFIG_LEVEL_MAX
+ TR_CONFIG_ON
+
+
+ TR_CONFIG_DIRECT3D
+ TR_CONFIG_TEXTURE_HIGH
+ 128
+ 1024
+ 576
+ Middle
+ 0
+ 1
+ 0
+ 0
+ X0
+ 60
+ TR_CONFIG_ON
+ TR_CONFIG_OFF
+ 0.4
+
+
+ Ambient
+ Blue
+ Blue
+ TR_CONFIG_ON
+ TR_CONFIG_ON
+ TR_CONFIG_TIMERLOOK_EXPANDED
+ TR_CONFIG_PLAYERINFO_BOTH
+ TR_CONFIG_FADEPLAYERINFO_OFF
+ TR_CONFIG_COVERLOADING_ATSTART
+ Slide
+
+
+ GstreamerSharp
+ PortAudio
+ B2048
+ 0
+ TR_CONFIG_ON
+ 20
+ TR_CONFIG_NO_OWN_MUSIC
+ TR_CONFIG_ON
+ 50
+ 100
+
+
+ Deutsch
+ E:\Songs
+ TR_CONFIG_TILE_BOARD
+ TR_CONFIG_ARTIST_LETTER
+ TR_CONFIG_ON
+ 10
+ TR_CONFIG_TIMERMODE_REMAINING
+ 1
+ TR_CONFIG_ON
+ TR_CONFIG_LYRICSPOSITION_BOTTOM
+ 0.1
+
+ guest1.xml
+ guest1.xml
+ guest1.xml
+ guest1.xml
+
+
+
+
+
+
+
+ Mikrofon (C-Media USB Headphone Set )
+ Mikrofon (C-Media USB Headphone Set )6
+ 1
+
+ 120
+
+
+ TR_CONFIG_ON
+ TR_CONFIG_ON
+ 3000
+
+
\ No newline at end of file
diff --git a/VocaluxeTests/TestXmlFiles/SDefaultFonts.xml b/VocaluxeTests/TestXmlFiles/SDefaultFonts.xml
new file mode 100644
index 00000000..ad954596
--- /dev/null
+++ b/VocaluxeTests/TestXmlFiles/SDefaultFonts.xml
@@ -0,0 +1,35 @@
+
+
+
+
+ Normal
+ 0
+
+ 0
+ 0
+ 0
+ 1
+
+ FreeSans
+ FreeSans.ttf
+ FreeSansBold.ttf
+ FreeSansOblique.ttf
+ FreeSansBoldOblique.ttf
+
+
+ Outline
+ 0.1
+
+ 0
+ 0
+ 0
+ 1
+
+ FreeSans
+ FreeSans.ttf
+ FreeSansBold.ttf
+ FreeSansOblique.ttf
+ FreeSansBoldOblique.ttf
+
+
+
\ No newline at end of file
diff --git a/VocaluxeTests/TestXmlFiles/SSkin.xml b/VocaluxeTests/TestXmlFiles/SSkin.xml
new file mode 100644
index 00000000..23f2a3df
--- /dev/null
+++ b/VocaluxeTests/TestXmlFiles/SSkin.xml
@@ -0,0 +1,268 @@
+
+
+ 4
+
+ Blue
+ bohning
+ 0
+ 0
+
+
+
+ 0
+ 0
+ 1
+ 1
+
+
+ 1
+ 0
+ 0
+ 1
+
+
+ 0
+ 1
+ 0
+ 1
+
+
+ 0.5
+ 0
+ 1
+ 1
+
+
+ 1
+ 0.8
+ 0
+ 1
+
+
+ 1
+ 0
+ 0.5
+ 1
+
+
+ 0
+ 0
+ 0.75
+ 1
+
+
+ 0.675
+ 0.89
+ 0.969
+ 1
+
+
+ 0.675
+ 0.89
+ 0.969
+ 0.5
+
+
+ 0.675
+ 0.89
+ 0.969
+ 0.6
+
+
+ 0.675
+ 0.89
+ 0.969
+ 0.3
+
+
+ 0.675
+ 0.89
+ 0.969
+ 1
+
+
+ 0.675
+ 0.89
+ 0.969
+ 0.5
+
+
+ 0.675
+ 0.89
+ 0.969
+ 1
+
+
+ 0.675
+ 0.89
+ 0.969
+ 1
+
+
+ 0.675
+ 0.89
+ 0.969
+ 0.5
+
+
+ 0.675
+ 0.89
+ 0.969
+ 0.5
+
+
+ 0.675
+ 0.89
+ 0.969
+ 0.3
+
+
+ 0.675
+ 0.89
+ 0.969
+ 1
+
+
+ 0.675
+ 0.89
+ 0.969
+ 0.5
+
+
+ 0.675
+ 0.89
+ 0.969
+ 1
+
+
+ 1
+ 0
+ 0
+ 1
+
+
+ 0
+ 0
+ 0
+ 1
+
+
+ 1
+ 1
+ 1
+ 1
+
+
+ 1
+ 1
+ 1
+ 1
+
+
+ 1
+ 1
+ 1
+ 0
+
+
+ 0
+ 0
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 1
+
+
+ 0.3
+ 0.3
+ 0.3
+ 1
+
+
+ 0
+ 0
+ 1
+ 0.5
+
+
+ 0.8
+ 0.95
+ 1
+ 0.5
+
+
+ 0.8
+ 0.95
+ 1
+ 0.85
+
+
+
+ [Blue]BG_Default.png
+ [Blue]BG_Options.png
+
+
+ CoverTile.png
+ CoverBackground.png
+ Cursor.png
+ TimeBar.png
+ TimeLine.png
+ Pointer.png
+ SelectSlide.png
+ SelectSlidePlayer.png
+ SelectSlideArrowLeft.png
+ SelectSlideArrowRight.png
+ notes_left.png
+ notes_mid.png
+ notes_right.png
+ notes_bg_left.png
+ notes_bg_mid.png
+ notes_bg_right.png
+ points_bar.png
+ points_bar_bg.png
+ Lyrics.png
+ LyricHelper.png
+ ToneHelper.png
+ TextBG.png
+ Score.png
+ Star.png
+ Snowflake.png
+ SongMenu.png
+ PerfectNoteStar.png
+ Pause.png
+ EnergyBeam.png
+ DuetIcon.png
+ VideoIcon.png
+ VideoIconCO.png
+ VideoIconBG.png
+ MedleyCalcIcon.png
+ MedleyTagIcon.png
+ PlayerSelector.png
+ PreviousIcon.png
+ NextIcon.png
+ PlayIcon.png
+ PauseIcon.png
+ RepeatIcon.png
+ SongMenuBG.png
+ Close.png
+ Delete.png
+ Save.png
+ Sing.png
+ Minus.png
+ Plus.png
+ Random.png
+ Popup.png
+ ScrollUp.png
+ ScrollDown.png
+
+
+ [Blue]BG_Video.mp4
+ [Blue]IntroIn.mp4
+ [Blue]IntroMid.mp4
+ [Blue]IntroOut.mp4
+
+
\ No newline at end of file
diff --git a/VocaluxeTests/TestXmlFiles/STheme.xml b/VocaluxeTests/TestXmlFiles/STheme.xml
new file mode 100644
index 00000000..91b0c674
--- /dev/null
+++ b/VocaluxeTests/TestXmlFiles/STheme.xml
@@ -0,0 +1,16 @@
+
+
+ 5
+
+ Ambient
+ bohning
+ 0
+ 2
+
+
+ Cursor
+ 40
+ 40
+
+
+
\ No newline at end of file
diff --git a/VocaluxeTests/TestXmlFiles/SThemeCover.xml b/VocaluxeTests/TestXmlFiles/SThemeCover.xml
new file mode 100644
index 00000000..bb43c51f
--- /dev/null
+++ b/VocaluxeTests/TestXmlFiles/SThemeCover.xml
@@ -0,0 +1,37 @@
+
+
+
+ Blue
+ Blue
+ flokuep
+
+
+
+ %TEXT%
+
+ Normal
+
+ 500
+
+
+ 1
+ 1
+ 1
+ 0.8
+
+
+ 24
+
+ 100
+
+
+ 1
+ 1
+ 1
+ 1
+
+ EmptyCover.png
+ 0.75
+ True
+
+
\ No newline at end of file
diff --git a/VocaluxeTests/TestXmlFiles/SThemeScreen.xml b/VocaluxeTests/TestXmlFiles/SThemeScreen.xml
new file mode 100644
index 00000000..a6751013
--- /dev/null
+++ b/VocaluxeTests/TestXmlFiles/SThemeScreen.xml
@@ -0,0 +1,256 @@
+
+
+
+ ScreenMain
+ 2
+
+
+
+ Video
+
+
+ BG_Default
+
+
+
+
+
+ Menu
+
+
+ 49
+ 32
+ 1181
+ 50
+ 0
+
+
+
+ TextBG
+
+
+ 150
+ 610
+ 355
+ 30
+ -1.9
+
+
+
+
+
+ 10
+ 690
+ -1
+ 15
+ 0
+
+
+ Left
+ Center
+
+ Normal
+ Vocaluxe "Shining Heaven" v0.3.0 (x64) Beta (0083)
+
+
+ 320
+ 612
+ -2
+ 27
+ 355
+
+
+ Center
+ Center
+
+ Outline
+ TR_SCREENMAIN_TEXT_NOPROFILES
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/VocaluxeTests/VocaluxeTests.csproj b/VocaluxeTests/VocaluxeTests.csproj
new file mode 100644
index 00000000..b3a0dade
--- /dev/null
+++ b/VocaluxeTests/VocaluxeTests.csproj
@@ -0,0 +1,113 @@
+
+
+
+ Debug
+ AnyCPU
+ {93356718-3A0B-4784-AAE1-215065BFFC66}
+ Library
+ Properties
+ VocaluxeTests
+ VocaluxeTests
+ v4.5
+ 512
+ {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 10.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+ $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
+ False
+ UnitTest
+
+
+ true
+ bin\x64\Debug\
+ TRACE;DEBUG
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE
+ full
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ bin\x86\Release\
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {d2b6ddef-e0e1-4ddf-a73a-e6acef5c95ec}
+ VocaluxeLib
+
+
+ {2a1e0f2d-5392-4bb7-b0a1-a9dfa13e79ff}
+ Vocaluxe
+
+
+
+
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/VocaluxeTests/XmlSerializerTest.cs b/VocaluxeTests/XmlSerializerTest.cs
new file mode 100644
index 00000000..9b89cdd1
--- /dev/null
+++ b/VocaluxeTests/XmlSerializerTest.cs
@@ -0,0 +1,302 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Xml;
+using System.Xml.Serialization;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Vocaluxe.Base;
+using VocaluxeLib;
+using VocaluxeLib.Menu;
+using VocaluxeLib.Xml;
+
+namespace VocaluxeTests
+{
+ [TestClass]
+ public class CXmlSerializerTest
+ {
+ private const string sHead = "\r\n";
+ private const string sEmpty = sHead + @"";
+
+ private struct SBasic
+ {
+ public int I;
+ public string S;
+ public float F;
+ public double D;
+ }
+
+ [TestMethod]
+ public void TestBasic()
+ {
+ const string s = @"
+ 1
+ 2
+ 3
+ 4
+";
+ var xml = new CXmlSerializer();
+ SBasic foo = xml.DeserializeString(s);
+ Assert.AreEqual(1, foo.I);
+ Assert.AreEqual("2", foo.S);
+ Assert.AreEqual(3, foo.F, 0.0001);
+ Assert.AreEqual(4, foo.D, 0.0001);
+ }
+
+ private static void _AssertFail(Action test) where T : Exception
+ {
+ try
+ {
+ test.Invoke();
+ Assert.Fail("Exception " + typeof(T).Name + " not thrown!");
+ }
+ catch (Exception e)
+ {
+ Assert.IsInstanceOfType(e, typeof(T));
+ }
+ }
+
+ [TestMethod]
+ public void TestMissingXmlElement()
+ {
+ string[] s = new string[] {@"
+ 2
+ 3
+ 4
+", @"
+ 1
+ 3
+ 4
+", @"
+ 1
+ 2
+ 3
+"};
+ var xml = new CXmlSerializer();
+ foreach (string s1 in s)
+ {
+ string sTmp = s1;
+ _AssertFail(() => xml.DeserializeString(sTmp));
+ }
+ }
+
+ [TestMethod]
+ public void TestMissingStructElement()
+ {
+ string[] s = new string[] {@"
+ 1
+ 1
+ 2
+ 3
+ 4
+", @"
+ 1
+ 1
+ 2
+ 3
+ 4
+", @"
+ 1
+ 2
+ 3
+ 4
+ 1
+"};
+ var xml = new CXmlSerializer();
+ foreach (string s1 in s)
+ {
+ string sTmp = s1;
+ _AssertFail(() => xml.DeserializeString(sTmp));
+ }
+ }
+
+ [TestMethod]
+ public void TestBasicSerialization()
+ {
+ const string s = sHead + @"
+ 1
+ 2
+ 3
+ 4
+";
+ var xml = new CXmlSerializer();
+ SBasic foo = xml.DeserializeString(s);
+ string s2 = xml.Serialize(foo);
+ Assert.AreEqual(s, s2);
+ }
+
+ private readonly string[] _XMLList = new string[]
+ {
+ sHead + @"
+
+
+ 1
+
+
+ 1
+
+
+",
+ sHead + @"
+
+
+",
+ sHead + @"
+
+"
+ };
+
+ [XmlType("Entry")]
+ private struct SEntry
+ {
+ public int I;
+ }
+
+ private struct SList
+ {
+ [XmlArray] public List Ints;
+ }
+
+ [TestMethod]
+ public void TestList()
+ {
+ var xml = new CXmlSerializer();
+ SList foo = xml.DeserializeString(_XMLList[0]);
+ Assert.AreEqual(foo.Ints.Count, 2, "Deserialization failed");
+ Assert.AreEqual(foo.Ints[0].I, 1, "Deserialization failed");
+ Assert.AreEqual(foo.Ints[1].I, 1, "Deserialization failed");
+ string res = xml.Serialize(foo);
+ Assert.AreEqual(_XMLList[0], res, "Serialization failed");
+ foo = xml.DeserializeString(_XMLList[1]);
+ Assert.AreEqual(foo.Ints.Count, 0, "Deserialization2 failed");
+ res = xml.Serialize(foo);
+ Assert.AreEqual(_XMLList[2], res, "Serialization2 failed");
+ foo = xml.DeserializeString(_XMLList[2]);
+ Assert.AreEqual(foo.Ints.Count, 0, "Deserialization2 failed");
+ res = xml.Serialize(foo);
+ Assert.AreEqual(_XMLList[2], res, "Serialization2 failed");
+ _AssertFail(() => xml.DeserializeString(sEmpty));
+ }
+
+ private struct SArray
+ {
+ [XmlArray] public SEntry[] Ints;
+ }
+
+ [TestMethod]
+ public void TestArray()
+ {
+ var xml = new CXmlSerializer();
+ SArray foo = xml.DeserializeString(_XMLList[0]);
+ Assert.AreEqual(foo.Ints.Length, 2, "Deserialization failed");
+ Assert.AreEqual(foo.Ints[0].I, 1, "Deserialization failed");
+ Assert.AreEqual(foo.Ints[1].I, 1, "Deserialization failed");
+ string res = xml.Serialize(foo);
+ Assert.AreEqual(_XMLList[0], res, "Serialization failed");
+ foo = xml.DeserializeString(_XMLList[1]);
+ Assert.AreEqual(foo.Ints.Length, 0, "Deserialization2 failed");
+ res = xml.Serialize(foo);
+ Assert.AreEqual(_XMLList[2], res, "Serialization2 failed");
+ foo = xml.DeserializeString(_XMLList[2]);
+ Assert.AreEqual(foo.Ints.Length, 0, "Deserialization2 failed");
+ res = xml.Serialize(foo);
+ Assert.AreEqual(_XMLList[2], res, "Serialization2 failed");
+ _AssertFail(() => xml.DeserializeString(sEmpty));
+ }
+
+ private const string _XMLListEmb = sHead + @"
+ 2
+
+ 1
+
+ 3
+";
+ private const string _XMLListEmb2 = sHead + @"
+ 2
+
+ 1
+
+
+ 2
+
+ 3
+";
+ private const string _XMLListEmb3 = sHead + @"
+ 2
+ 3
+";
+
+ private struct SListEmb
+ {
+ public int I;
+ [XmlElement("Entry")] public List Ints;
+ public int J;
+ }
+
+ [TestMethod]
+ public void TestListEmbedded()
+ {
+ var xml = new CXmlSerializer();
+ SListEmb foo = xml.DeserializeString(_XMLListEmb);
+ Assert.AreEqual(foo.Ints.Count, 1, "Deserialization failed");
+ Assert.AreEqual(foo.Ints[0].I, 1, "Deserialization failed");
+ string res = xml.Serialize(foo);
+ Assert.AreEqual(_XMLListEmb, res, "Serialization failed");
+ foo = xml.DeserializeString(_XMLListEmb2);
+ Assert.AreEqual(foo.Ints.Count, 2, "Deserialization failed");
+ Assert.AreEqual(foo.Ints[1].I, 2, "Deserialization failed");
+ res = xml.Serialize(foo);
+ Assert.AreEqual(_XMLListEmb2, res, "Serialization failed");
+ foo = xml.DeserializeString(_XMLListEmb3);
+ Assert.AreEqual(foo.Ints.Count, 0, "Deserialization failed");
+ res = xml.Serialize(foo);
+ Assert.AreEqual(_XMLListEmb3, res, "Serialization failed");
+ _AssertFail(() => xml.DeserializeString(sEmpty));
+ }
+
+ private struct SArrayEmb
+ {
+ public int I;
+ [XmlElement("Entry")] public SEntry[] Ints;
+ public int J;
+ }
+
+ [TestMethod]
+ public void TestArrayEmbedded()
+ {
+ var xml = new CXmlSerializer();
+ SArrayEmb foo = xml.DeserializeString(_XMLListEmb);
+ Assert.AreEqual(foo.Ints.Length, 1, "Deserialization failed");
+ Assert.AreEqual(foo.Ints[0].I, 1, "Deserialization failed");
+ string res = xml.Serialize(foo);
+ Assert.AreEqual(_XMLListEmb, res, "Serialization failed");
+ foo = xml.DeserializeString(_XMLListEmb2);
+ Assert.AreEqual(foo.Ints.Length, 2, "Deserialization failed");
+ Assert.AreEqual(foo.Ints[1].I, 2, "Deserialization failed");
+ res = xml.Serialize(foo);
+ Assert.AreEqual(_XMLListEmb2, res, "Serialization failed");
+ foo = xml.DeserializeString(_XMLListEmb3);
+ Assert.AreEqual(foo.Ints.Length, 0, "Deserialization failed");
+ res = xml.Serialize(foo);
+ Assert.AreEqual(_XMLListEmb3, res, "Serialization failed");
+ _AssertFail(() => xml.DeserializeString(sEmpty));
+ }
+
+ [TestMethod]
+ public void TestRealFiles()
+ {
+ Type[] types = new Type[] {typeof(SThemeCover), typeof(CConfig.SConfig), typeof(SThemeScreen), typeof(SDefaultFonts), typeof(SSkin), typeof(STheme)};
+ string filePath = Path.Combine(new string[] {AppDomain.CurrentDomain.BaseDirectory, "..", "..", "..", "TestXmlFiles"});
+ foreach (Type type in types)
+ {
+ string xmlPath = Path.Combine(filePath, type.Name + ".xml");
+ var xml = new CXmlSerializer(type == typeof(CConfig.SConfig));
+ object foo = xml.GetType().GetMethod("Deserialize").MakeGenericMethod(new Type[] {type}).Invoke(xml, new object[] {xmlPath});
+ Assert.IsInstanceOfType(foo, type);
+ string newXml = xml.Serialize(foo);
+ string oldXml = File.ReadAllText(xmlPath);
+ Assert.AreEqual(oldXml, newXml, "Error in " + type.Name);
+ }
+ }
+ }
+}
\ No newline at end of file