From f14916432e4b12632d31cd8ac40c2420a1659d17 Mon Sep 17 00:00:00 2001 From: markrendle Date: Wed, 10 Nov 2010 09:36:08 +0000 Subject: [PATCH] Integrated Simple.NExtLib into solution --- Simple.Data.sln | 19 ++ .../DateTimeExtensionsTests.cs | 20 +++ .../Linq/EnumerableExtensionTests.cs | 25 +++ .../Properties/AssemblyInfo.cs | 36 ++++ .../Properties/Resources.Designer.cs | 138 +++++++++++++++ .../Properties/Resources.resx | 134 ++++++++++++++ .../Resources/TwitterStatusesSample.txt | 78 ++++++++ .../Resources/XmlWithDefaultNamespace.txt | 9 + .../Resources/XmlWithNoNamespace.txt | 9 + .../Resources/XmlWithPrefixedNamespace.txt | 9 + .../Simple.NExtLib.Tests.csproj | 95 ++++++++++ Simple.NExtLib.Tests/StringExtensionTests.cs | 30 ++++ .../Xml/Linq/XElementExtensionsTests.cs | 44 +++++ .../Xml/XmlAttributesAsDictionaryReadTests.cs | 36 ++++ .../XmlAttributesAsDictionaryWriteTests.cs | 42 +++++ .../Xml/XmlElementAsDictionaryReadTests.cs | 46 +++++ .../Xml/XmlElementAsDictionaryWriteTests.cs | 93 ++++++++++ Simple.NExtLib.Unit/ContainTest.cs | 16 ++ Simple.NExtLib.Unit/EqualTest.cs | 16 ++ Simple.NExtLib.Unit/GenericBinaryTest.cs | 11 ++ Simple.NExtLib.Unit/IBinaryTest.cs | 12 ++ Simple.NExtLib.Unit/IEnumerableTest.cs | 12 ++ .../Properties/AssemblyInfo.cs | 36 ++++ Simple.NExtLib.Unit/ShouldExtensions.cs | 48 +++++ .../Simple.NExtLib.Unit.csproj | 61 +++++++ Simple.NExtLib.Unit/TestBase.cs | 13 ++ Simple.NExtLib/Async/AsyncException.cs | 19 ++ Simple.NExtLib/Async/Future.cs | 23 +++ Simple.NExtLib/Async/Future`1.cs | 63 +++++++ Simple.NExtLib/DateTimeExtensions.cs | 20 +++ Simple.NExtLib/Func.cs | 16 ++ Simple.NExtLib/IO/QuickIO.cs | 28 +++ Simple.NExtLib/Linq/EnumerableExtensions.cs | 21 +++ .../EnumerableOfKeyValuePairExtensions.cs | 34 ++++ .../Linq/TupleEnumerableExtensions.cs | 82 +++++++++ Simple.NExtLib/Properties/AssemblyInfo.cs | 36 ++++ .../Properties/Resources.Designer.cs | 72 ++++++++ Simple.NExtLib/Properties/Resources.resx | 123 +++++++++++++ Simple.NExtLib/Simple.NExtLib.csproj | 86 +++++++++ Simple.NExtLib/StringExtensions.cs | 15 ++ Simple.NExtLib/TupleExtensions.cs | 23 +++ .../Xml/Linq/XAttributeExtensions.cs | 21 +++ Simple.NExtLib/Xml/Linq/XElementExtensions.cs | 59 +++++++ .../Syndication/SyndicationItemExtensions.cs | 34 ++++ .../Xml/XElementAsDictionaryExtension.cs | 47 +++++ .../Xml/XmlAttributesAsDictionary.cs | 43 +++++ Simple.NExtLib/Xml/XmlElementAsDictionary.cs | 167 ++++++++++++++++++ 47 files changed, 2120 insertions(+) create mode 100644 Simple.NExtLib.Tests/DateTimeExtensionsTests.cs create mode 100644 Simple.NExtLib.Tests/Linq/EnumerableExtensionTests.cs create mode 100644 Simple.NExtLib.Tests/Properties/AssemblyInfo.cs create mode 100644 Simple.NExtLib.Tests/Properties/Resources.Designer.cs create mode 100644 Simple.NExtLib.Tests/Properties/Resources.resx create mode 100644 Simple.NExtLib.Tests/Resources/TwitterStatusesSample.txt create mode 100644 Simple.NExtLib.Tests/Resources/XmlWithDefaultNamespace.txt create mode 100644 Simple.NExtLib.Tests/Resources/XmlWithNoNamespace.txt create mode 100644 Simple.NExtLib.Tests/Resources/XmlWithPrefixedNamespace.txt create mode 100644 Simple.NExtLib.Tests/Simple.NExtLib.Tests.csproj create mode 100644 Simple.NExtLib.Tests/StringExtensionTests.cs create mode 100644 Simple.NExtLib.Tests/Xml/Linq/XElementExtensionsTests.cs create mode 100644 Simple.NExtLib.Tests/Xml/XmlAttributesAsDictionaryReadTests.cs create mode 100644 Simple.NExtLib.Tests/Xml/XmlAttributesAsDictionaryWriteTests.cs create mode 100644 Simple.NExtLib.Tests/Xml/XmlElementAsDictionaryReadTests.cs create mode 100644 Simple.NExtLib.Tests/Xml/XmlElementAsDictionaryWriteTests.cs create mode 100644 Simple.NExtLib.Unit/ContainTest.cs create mode 100644 Simple.NExtLib.Unit/EqualTest.cs create mode 100644 Simple.NExtLib.Unit/GenericBinaryTest.cs create mode 100644 Simple.NExtLib.Unit/IBinaryTest.cs create mode 100644 Simple.NExtLib.Unit/IEnumerableTest.cs create mode 100644 Simple.NExtLib.Unit/Properties/AssemblyInfo.cs create mode 100644 Simple.NExtLib.Unit/ShouldExtensions.cs create mode 100644 Simple.NExtLib.Unit/Simple.NExtLib.Unit.csproj create mode 100644 Simple.NExtLib.Unit/TestBase.cs create mode 100644 Simple.NExtLib/Async/AsyncException.cs create mode 100644 Simple.NExtLib/Async/Future.cs create mode 100644 Simple.NExtLib/Async/Future`1.cs create mode 100644 Simple.NExtLib/DateTimeExtensions.cs create mode 100644 Simple.NExtLib/Func.cs create mode 100644 Simple.NExtLib/IO/QuickIO.cs create mode 100644 Simple.NExtLib/Linq/EnumerableExtensions.cs create mode 100644 Simple.NExtLib/Linq/EnumerableOfKeyValuePairExtensions.cs create mode 100644 Simple.NExtLib/Linq/TupleEnumerableExtensions.cs create mode 100644 Simple.NExtLib/Properties/AssemblyInfo.cs create mode 100644 Simple.NExtLib/Properties/Resources.Designer.cs create mode 100644 Simple.NExtLib/Properties/Resources.resx create mode 100644 Simple.NExtLib/Simple.NExtLib.csproj create mode 100644 Simple.NExtLib/StringExtensions.cs create mode 100644 Simple.NExtLib/TupleExtensions.cs create mode 100644 Simple.NExtLib/Xml/Linq/XAttributeExtensions.cs create mode 100644 Simple.NExtLib/Xml/Linq/XElementExtensions.cs create mode 100644 Simple.NExtLib/Xml/Syndication/SyndicationItemExtensions.cs create mode 100644 Simple.NExtLib/Xml/XElementAsDictionaryExtension.cs create mode 100644 Simple.NExtLib/Xml/XmlAttributesAsDictionary.cs create mode 100644 Simple.NExtLib/Xml/XmlElementAsDictionary.cs diff --git a/Simple.Data.sln b/Simple.Data.sln index ffb47414..6211c21e 100644 --- a/Simple.Data.sln +++ b/Simple.Data.sln @@ -40,6 +40,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simple.Data.SqlCe35Test", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simple.Data.SqlServer", "Simple.Data.SqlServer\Simple.Data.SqlServer.csproj", "{E24F1C0F-3DCD-4BE5-9A6E-78EF6CB392A1}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simple.NExtLib", "Simple.NExtLib\Simple.NExtLib.csproj", "{4A191FAD-DC1D-46FC-A941-7DEB2C8C4C15}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simple.NExtLib.Unit", "Simple.NExtLib.Unit\Simple.NExtLib.Unit.csproj", "{072F8BE4-81C1-4276-A9A5-1AEC87A84265}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simple.NExtLib.Tests", "Simple.NExtLib.Tests\Simple.NExtLib.Tests.csproj", "{8DF17038-537D-45BE-B229-C99EECBB4EDC}" +EndProject Global GlobalSection(TestCaseManagementSettings) = postSolution CategoryFile = Simple.Data.vsmdi @@ -91,6 +97,18 @@ Global {E24F1C0F-3DCD-4BE5-9A6E-78EF6CB392A1}.Debug|Any CPU.Build.0 = Debug|Any CPU {E24F1C0F-3DCD-4BE5-9A6E-78EF6CB392A1}.Release|Any CPU.ActiveCfg = Release|Any CPU {E24F1C0F-3DCD-4BE5-9A6E-78EF6CB392A1}.Release|Any CPU.Build.0 = Release|Any CPU + {4A191FAD-DC1D-46FC-A941-7DEB2C8C4C15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A191FAD-DC1D-46FC-A941-7DEB2C8C4C15}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A191FAD-DC1D-46FC-A941-7DEB2C8C4C15}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A191FAD-DC1D-46FC-A941-7DEB2C8C4C15}.Release|Any CPU.Build.0 = Release|Any CPU + {072F8BE4-81C1-4276-A9A5-1AEC87A84265}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {072F8BE4-81C1-4276-A9A5-1AEC87A84265}.Debug|Any CPU.Build.0 = Debug|Any CPU + {072F8BE4-81C1-4276-A9A5-1AEC87A84265}.Release|Any CPU.ActiveCfg = Release|Any CPU + {072F8BE4-81C1-4276-A9A5-1AEC87A84265}.Release|Any CPU.Build.0 = Release|Any CPU + {8DF17038-537D-45BE-B229-C99EECBB4EDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8DF17038-537D-45BE-B229-C99EECBB4EDC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8DF17038-537D-45BE-B229-C99EECBB4EDC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8DF17038-537D-45BE-B229-C99EECBB4EDC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -102,5 +120,6 @@ Global {70536BA8-AF0D-46F3-B04C-45177F56B320} = {182AEEFE-9B89-4264-BCED-91A00D1EF896} {D4FE470E-4B01-4120-B809-F426A0179191} = {182AEEFE-9B89-4264-BCED-91A00D1EF896} {29BBCAE1-DF13-40A0-A412-F2F87F4E9351} = {182AEEFE-9B89-4264-BCED-91A00D1EF896} + {8DF17038-537D-45BE-B229-C99EECBB4EDC} = {182AEEFE-9B89-4264-BCED-91A00D1EF896} EndGlobalSection EndGlobal diff --git a/Simple.NExtLib.Tests/DateTimeExtensionsTests.cs b/Simple.NExtLib.Tests/DateTimeExtensionsTests.cs new file mode 100644 index 00000000..8560b0f0 --- /dev/null +++ b/Simple.NExtLib.Tests/DateTimeExtensionsTests.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; + +namespace Simple.NExtLib.Tests +{ + [TestFixture] + public class DateTimeExtensionsTests : AssertionHelper + { + [Test] + public void ToIso8601String_formats_dates_correctly() + { + var date = new DateTime(2010, 2, 17, 13, 12, 34, 0, DateTimeKind.Utc); + + Assert.That(date.ToIso8601String(), Is.EqualTo("2010-02-17T13:12:34.0000000Z")); + } + } +} diff --git a/Simple.NExtLib.Tests/Linq/EnumerableExtensionTests.cs b/Simple.NExtLib.Tests/Linq/EnumerableExtensionTests.cs new file mode 100644 index 00000000..6772b031 --- /dev/null +++ b/Simple.NExtLib.Tests/Linq/EnumerableExtensionTests.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using NExtLib.Unit; +using NUnit.Framework; +using Simple.NExtLib.Linq; + +namespace Simple.NExtLib.Tests.Linq +{ + [TestFixture] + public class EnumerableExtensionTests + { + private readonly IEnumerable TestList = new List { "Foo", "Bar", "Quux" }; + + [Test] + public void TestWithIndex() + { + int expectedIndex = 0; + + foreach (var item in TestList.WithIndex()) + { + item.Item2.ShouldEqual(expectedIndex); + expectedIndex++; + } + } + } +} diff --git a/Simple.NExtLib.Tests/Properties/AssemblyInfo.cs b/Simple.NExtLib.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..7706c62b --- /dev/null +++ b/Simple.NExtLib.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("NExtLib.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("NExtLib.Tests")] +[assembly: AssemblyCopyright("Copyright © Mark Rendle 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("fc845d30-b32d-4e62-86c8-0999a399e720")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.1.0.0")] +[assembly: AssemblyFileVersion("0.1.0.0")] diff --git a/Simple.NExtLib.Tests/Properties/Resources.Designer.cs b/Simple.NExtLib.Tests/Properties/Resources.Designer.cs new file mode 100644 index 00000000..e72359b1 --- /dev/null +++ b/Simple.NExtLib.Tests/Properties/Resources.Designer.cs @@ -0,0 +1,138 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.1 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Simple.NExtLib.Tests.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Simple.NExtLib.Tests.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="UTF-8"?> + ///<statuses> + ///<status> + ///<created_at>Tue Apr 07 22:52:51 +0000 2009</created_at> + ///<id>1472669360</id> + ///<text>Tweet one.</text> + ///<source><a href="http://www.tweetdeck.com/">TweetDeck</a></source> + ///<truncated>false</truncated> + ///<in_reply_to_status_id></in_reply_to_status_id> + ///<in_reply_to_user_id></in_reply_to_user_id> + ///<favorited>false</favorited> + ///<in_reply_to_screen_name></in_reply_to_screen_name> + ///<user> + ///<id>1401881</id> + ///<name>Doug Williams</name> + ///<screen_name>dougw [rest of string was truncated]";. + /// + internal static string TwitterStatusesSample { + get { + return ResourceManager.GetString("TwitterStatusesSample", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> + ///<root xmlns="http://schemas.next.lib/tests"> + /// <child> + /// <sub>Foo</sub> + /// </child> + /// <child> + /// <sub>Bar</sub> + /// </child> + ///</root>. + /// + internal static string XmlWithDefaultNamespace { + get { + return ResourceManager.GetString("XmlWithDefaultNamespace", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> + ///<root> + /// <child> + /// <sub>Foo</sub> + /// </child> + /// <child> + /// <sub>Bar</sub> + /// </child> + ///</root>. + /// + internal static string XmlWithNoNamespace { + get { + return ResourceManager.GetString("XmlWithNoNamespace", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> + ///<root xmlns:c="http://schemas.next.lib/tests"> + /// <c:child> + /// <c:sub>Foo</c:sub> + /// </c:child> + /// <c:child> + /// <c:sub>Bar</c:sub> + /// </c:child> + ///</root>. + /// + internal static string XmlWithPrefixedNamespace { + get { + return ResourceManager.GetString("XmlWithPrefixedNamespace", resourceCulture); + } + } + } +} diff --git a/Simple.NExtLib.Tests/Properties/Resources.resx b/Simple.NExtLib.Tests/Properties/Resources.resx new file mode 100644 index 00000000..0d137fa5 --- /dev/null +++ b/Simple.NExtLib.Tests/Properties/Resources.resx @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\TwitterStatusesSample.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + + ..\Resources\XmlWithDefaultNamespace.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\XmlWithNoNamespace.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\XmlWithPrefixedNamespace.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + \ No newline at end of file diff --git a/Simple.NExtLib.Tests/Resources/TwitterStatusesSample.txt b/Simple.NExtLib.Tests/Resources/TwitterStatusesSample.txt new file mode 100644 index 00000000..2b753969 --- /dev/null +++ b/Simple.NExtLib.Tests/Resources/TwitterStatusesSample.txt @@ -0,0 +1,78 @@ + + + +Tue Apr 07 22:52:51 +0000 2009 +1472669360 +Tweet one. +TweetDeck +false + + +false + + +1401881 +Doug Williams +dougw +San Francisco, CA +Twitter API Support. Internet, greed, users, dougw and opportunities are my passions. +http://s3.amazonaws.com/twitter_production/profile_images/59648642/avatar_normal.png +http://www.igudo.com +false +1027 +9ae4e8 +000000 +0000ff +e0ff92 +87bc44 +293 +Sun Mar 18 06:42:26 +0000 2007 +0 +-18000 +Eastern Time (US & Canada) +http://s3.amazonaws.com/twitter_production/profile_background_images/2752608/twitter_bg_grass.jpg +false +3390 +false +false +true + + + +Tue Apr 07 22:55:51 +0000 2009 +1472669365 +Tweet two. +TweetDeck +false + + +false + + +1401881 +Doug Williams +dougw +San Francisco, CA +Twitter API Support. Internet, greed, users, dougw and opportunities are my passions. +http://s3.amazonaws.com/twitter_production/profile_images/59648642/avatar_normal.png +http://www.igudo.com +false +1027 +9ae4e8 +000000 +0000ff +e0ff92 +87bc44 +293 +Sun Mar 18 06:42:26 +0000 2007 +0 +-18000 +Eastern Time (US & Canada) +http://s3.amazonaws.com/twitter_production/profile_background_images/2752608/twitter_bg_grass.jpg +false +3390 +false +false +true + + \ No newline at end of file diff --git a/Simple.NExtLib.Tests/Resources/XmlWithDefaultNamespace.txt b/Simple.NExtLib.Tests/Resources/XmlWithDefaultNamespace.txt new file mode 100644 index 00000000..0c4faebb --- /dev/null +++ b/Simple.NExtLib.Tests/Resources/XmlWithDefaultNamespace.txt @@ -0,0 +1,9 @@ + + + + Foo + + + Bar + + \ No newline at end of file diff --git a/Simple.NExtLib.Tests/Resources/XmlWithNoNamespace.txt b/Simple.NExtLib.Tests/Resources/XmlWithNoNamespace.txt new file mode 100644 index 00000000..1c400e6e --- /dev/null +++ b/Simple.NExtLib.Tests/Resources/XmlWithNoNamespace.txt @@ -0,0 +1,9 @@ + + + + Foo + + + Bar + + \ No newline at end of file diff --git a/Simple.NExtLib.Tests/Resources/XmlWithPrefixedNamespace.txt b/Simple.NExtLib.Tests/Resources/XmlWithPrefixedNamespace.txt new file mode 100644 index 00000000..2bbd102a --- /dev/null +++ b/Simple.NExtLib.Tests/Resources/XmlWithPrefixedNamespace.txt @@ -0,0 +1,9 @@ + + + + Foo + + + Bar + + \ No newline at end of file diff --git a/Simple.NExtLib.Tests/Simple.NExtLib.Tests.csproj b/Simple.NExtLib.Tests/Simple.NExtLib.Tests.csproj new file mode 100644 index 00000000..19ed7c37 --- /dev/null +++ b/Simple.NExtLib.Tests/Simple.NExtLib.Tests.csproj @@ -0,0 +1,95 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {8DF17038-537D-45BE-B229-C99EECBB4EDC} + Library + Properties + Simple.NExtLib.Tests + Simple.NExtLib.Tests + v4.0 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + + + + + + + + + + + + {072F8BE4-81C1-4276-A9A5-1AEC87A84265} + Simple.NExtLib.Unit + + + {4A191FAD-DC1D-46FC-A941-7DEB2C8C4C15} + Simple.NExtLib + + + + + \ No newline at end of file diff --git a/Simple.NExtLib.Tests/StringExtensionTests.cs b/Simple.NExtLib.Tests/StringExtensionTests.cs new file mode 100644 index 00000000..5ea740e5 --- /dev/null +++ b/Simple.NExtLib.Tests/StringExtensionTests.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using NExtLib; +using NExtLib.Unit; + +namespace Simple.NExtLib.Tests +{ + [TestFixture] + public class StringExtensionTests : AssertionHelper + { + [Test] + public void EnsureStartsWith_should_prefix_string() + { + var actual = "bar".EnsureStartsWith("foo"); + + actual.ShouldEqual("foobar"); + } + + [Test] + public void EnsureStartsWith_should_not_prefix_string() + { + var actual = "foobar".EnsureStartsWith("foo"); + + actual.ShouldEqual("foobar"); + } + } +} diff --git a/Simple.NExtLib.Tests/Xml/Linq/XElementExtensionsTests.cs b/Simple.NExtLib.Tests/Xml/Linq/XElementExtensionsTests.cs new file mode 100644 index 00000000..7c7a92f6 --- /dev/null +++ b/Simple.NExtLib.Tests/Xml/Linq/XElementExtensionsTests.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using System.Xml.Linq; +using NExtLib.Unit; + +namespace Simple.NExtLib.Tests.Xml.Linq +{ + [TestFixture] + public class XElementExtensionsTests + { + [Test] + public void TestXElementWithDefaultNamespace() + { + var element = XElement.Parse(Properties.Resources.XmlWithDefaultNamespace); + var list = element.Elements(null, "child").ToList(); + list.Count.ShouldEqual(2); + list[0].Element(null, "sub").Value.ShouldEqual("Foo"); + list[1].Element(null, "sub").Value.ShouldEqual("Bar"); + } + + [Test] + public void TestXElementWithNoNamespace() + { + var element = XElement.Parse(Properties.Resources.XmlWithNoNamespace); + var list = element.Elements(null, "child").ToList(); + list.Count.ShouldEqual(2); + list[0].Element(null, "sub").Value.ShouldEqual("Foo"); + list[1].Element(null, "sub").Value.ShouldEqual("Bar"); + } + + [Test] + public void TestXElementWithPrefixedNamespace() + { + var element = XElement.Parse(Properties.Resources.XmlWithPrefixedNamespace); + var list = element.Elements("c", "child").ToList(); + list.Count.ShouldEqual(2); + list[0].Element("c", "sub").Value.ShouldEqual("Foo"); + list[1].Element("c", "sub").Value.ShouldEqual("Bar"); + } + } +} diff --git a/Simple.NExtLib.Tests/Xml/XmlAttributesAsDictionaryReadTests.cs b/Simple.NExtLib.Tests/Xml/XmlAttributesAsDictionaryReadTests.cs new file mode 100644 index 00000000..d673fa81 --- /dev/null +++ b/Simple.NExtLib.Tests/Xml/XmlAttributesAsDictionaryReadTests.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NExtLib.Unit; +using NUnit.Framework; +using System.Xml.Linq; +using Simple.NExtLib.Xml; + +namespace Simple.NExtLib.Tests.Xml +{ + [TestFixture] + public class XmlAttributesAsDictionaryReadTests + { + [Test] + public void ReadWithNoNamespace() + { + var xml = new XmlElementAsDictionary(XElement.Parse(@"")); + xml.Attributes["bar"].ShouldEqual("quux"); + } + + [Test] + public void ReadWithDefaultNamespace() + { + var xml = new XmlElementAsDictionary(XElement.Parse(@"")); + xml.Attributes["bar"].ShouldEqual("quux"); + } + + [Test] + public void ReadWithPrefixedNamespace() + { + var xml = new XmlElementAsDictionary(XElement.Parse(@"")); + xml.Attributes["q:bar"].ShouldEqual("quux"); + } + } +} diff --git a/Simple.NExtLib.Tests/Xml/XmlAttributesAsDictionaryWriteTests.cs b/Simple.NExtLib.Tests/Xml/XmlAttributesAsDictionaryWriteTests.cs new file mode 100644 index 00000000..22253e62 --- /dev/null +++ b/Simple.NExtLib.Tests/Xml/XmlAttributesAsDictionaryWriteTests.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NExtLib.Unit; +using NUnit.Framework; +using Simple.NExtLib.Xml; + +namespace Simple.NExtLib.Tests.Xml +{ + [TestFixture] + public class XmlAttributesAsDictionaryWriteTests + { + [Test] + public void PlainAttributeValueCheck() + { + var xml = new XmlElementAsDictionary("foo"); + xml.Attributes["bar"] = "quux"; + + xml.ToElement().Attribute("bar").Value.ShouldEqual("quux"); + } + + [Test] + public void DefaultNamespaceAttributeValueCheck() + { + var xml = new XmlElementAsDictionary("foo", "www.test.org"); + xml.Attributes["bar"] = "quux"; + + xml.ToElement().Attribute(xml.ToElement().GetDefaultNamespace() + "bar").Value.ShouldEqual("quux"); + } + + [Test] + public void PrefixedNamespaceAttributeValueCheck() + { + var xml = new XmlElementAsDictionary("foo"); + xml.AddPrefixedNamespace("q", "www.test.org"); + xml.Attributes["q:bar"] = "quux"; + + xml.ToElement().Attribute(xml.ToElement().GetNamespaceOfPrefix("q") + "bar").Value.ShouldEqual("quux"); + } + } +} diff --git a/Simple.NExtLib.Tests/Xml/XmlElementAsDictionaryReadTests.cs b/Simple.NExtLib.Tests/Xml/XmlElementAsDictionaryReadTests.cs new file mode 100644 index 00000000..cf31ef28 --- /dev/null +++ b/Simple.NExtLib.Tests/Xml/XmlElementAsDictionaryReadTests.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using System.Linq; +using NExtLib.Unit; +using NUnit.Framework; +using Simple.NExtLib.Tests.Properties; +using Simple.NExtLib.Xml; + +namespace Simple.NExtLib.Tests.Xml +{ + [TestFixture] + public class XmlElementAsDictionaryReadTests + { + private static IEnumerable ParseDescendantsUnderTest + { + get { return XmlElementAsDictionary.ParseDescendants(Resources.TwitterStatusesSample, "status"); } + } + + [Test] + public void FirstDescendantIsTweetOne() + { + XmlElementAsDictionary actual = ParseDescendantsUnderTest.First(); + actual["text"].Value.ShouldEqual("Tweet one."); + } + + [Test] + public void SecondDescendantIsTweetTwo() + { + XmlElementAsDictionary actual = ParseDescendantsUnderTest.Skip(1).First(); + actual["text"].Value.ShouldEqual("Tweet two."); + } + + [Test] + public void ParseDescendantsReturnsTwoItems() + { + ParseDescendantsUnderTest.Count().ShouldEqual(2); + } + + [Test] + public void UserNameReturnedCorrectly() + { + var one = ParseDescendantsUnderTest.First(); + + one["user"]["name"].Value.ShouldEqual("Doug Williams"); + } + } +} \ No newline at end of file diff --git a/Simple.NExtLib.Tests/Xml/XmlElementAsDictionaryWriteTests.cs b/Simple.NExtLib.Tests/Xml/XmlElementAsDictionaryWriteTests.cs new file mode 100644 index 00000000..13700561 --- /dev/null +++ b/Simple.NExtLib.Tests/Xml/XmlElementAsDictionaryWriteTests.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NExtLib.Unit; +using NUnit.Framework; +using System.Xml.Linq; +using System.Diagnostics; +using Simple.NExtLib.Xml; + +namespace Simple.NExtLib.Tests.Xml +{ + [TestFixture] + public class XmlElementAsDictionaryWriteTests + { + [Test] + public void StringConstructorShouldCreateEmptyElementWithNoNamespace() + { + var actual = new XmlElementAsDictionary("foo"); + + actual.ToElement().Name.LocalName.ShouldEqual("foo"); + actual.ToElement().Name.Namespace.ShouldEqual(XNamespace.None); + } + + [Test] + public void TwoStringConstructorShouldCreateEmptyElementWithNamespace() + { + var actual = new XmlElementAsDictionary("foo", "www.test.org"); + + actual.ToElement().Name.LocalName.ShouldEqual("foo"); + actual.ToElement().Name.Namespace.NamespaceName.ShouldEqual("www.test.org"); + } + + [Test] + public void TwoStringConstructorWithPrefixShouldCreateEmptyElementWithPrefixedNamespace() + { + var actual = new XmlElementAsDictionary("a:foo", "www.test.org"); + + actual.ToElement().Name.LocalName.ShouldEqual("foo"); + actual.ToElement().Name.Namespace.ShouldEqual(actual.ToElement().GetNamespaceOfPrefix("a")); + actual.Attributes["xmlns:a"].ShouldEqual("www.test.org"); + } + + [Test] + public void UnsetAttributeShouldBeNull() + { + var actual = new XmlElementAsDictionary("foo"); + actual.Attributes["bar"].ShouldBeNull(); + } + + [Test] + public void SetAttributeShouldBeSet() + { + var actual = new XmlElementAsDictionary("foo"); + actual.Attributes["bar"] = "Fnord"; + actual.Attributes["bar"].ShouldEqual("Fnord"); + } + + [Test] + public void AttributeWithPrefixShouldHaveCorrectNamespace() + { + var actual = new XmlElementAsDictionary("foo"); + actual.AddPrefixedNamespace("x", "www.test.org"); + actual.Attributes["x:bar"] = "Fnord"; + + var xname = actual.ToElement().GetNamespaceOfPrefix("x") + "bar"; + XAttribute attr; + (attr = actual.ToElement().Attribute(xname)).ShouldNotBeNull(); + attr.Value.ShouldEqual("Fnord"); + } + + [Test] + public void EmptyElementCreationWithClear() + { + var xml = new XmlElementAsDictionary("foo"); + xml["bar"].Clear(); + var actual = xml.ToElement(); + actual.ShouldNotBeNull(); + actual.Value.ShouldEqual(string.Empty); + } + + [Test] + public void CountShouldGetReflectNumberOfElements() + { + var xml = new XmlElementAsDictionary("foo"); + xml["bar"].Clear(); + + xml.Count.ShouldEqual(1); + + xml.ToElement().Elements().Count().ShouldEqual(1); + } + } +} diff --git a/Simple.NExtLib.Unit/ContainTest.cs b/Simple.NExtLib.Unit/ContainTest.cs new file mode 100644 index 00000000..ab875492 --- /dev/null +++ b/Simple.NExtLib.Unit/ContainTest.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; + +namespace NExtLib.TestExtensions +{ + public class ContainTest : IEnumerableTest + { + public void RunTest(T expected, IEnumerable actual) + { + Assert.IsTrue(actual.Contains(expected)); + } + } +} diff --git a/Simple.NExtLib.Unit/EqualTest.cs b/Simple.NExtLib.Unit/EqualTest.cs new file mode 100644 index 00000000..20259f25 --- /dev/null +++ b/Simple.NExtLib.Unit/EqualTest.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; + +namespace NExtLib.TestExtensions +{ + public class EqualTest : IBinaryTest + { + public void Run(T expected, T actual) + { + Assert.AreEqual(expected, actual); + } + } +} diff --git a/Simple.NExtLib.Unit/GenericBinaryTest.cs b/Simple.NExtLib.Unit/GenericBinaryTest.cs new file mode 100644 index 00000000..93d084b4 --- /dev/null +++ b/Simple.NExtLib.Unit/GenericBinaryTest.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NExtLib.TestExtensions +{ + public class GenericBinaryTest + { + } +} diff --git a/Simple.NExtLib.Unit/IBinaryTest.cs b/Simple.NExtLib.Unit/IBinaryTest.cs new file mode 100644 index 00000000..1afc4636 --- /dev/null +++ b/Simple.NExtLib.Unit/IBinaryTest.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NExtLib.TestExtensions +{ + public interface IBinaryTest + { + void Run(T expected, T actual); + } +} diff --git a/Simple.NExtLib.Unit/IEnumerableTest.cs b/Simple.NExtLib.Unit/IEnumerableTest.cs new file mode 100644 index 00000000..f2837e95 --- /dev/null +++ b/Simple.NExtLib.Unit/IEnumerableTest.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NExtLib.TestExtensions +{ + public interface IEnumerableTest + { + void RunTest(T expected, IEnumerable actual); + } +} diff --git a/Simple.NExtLib.Unit/Properties/AssemblyInfo.cs b/Simple.NExtLib.Unit/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..cd3047bb --- /dev/null +++ b/Simple.NExtLib.Unit/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("NExtLib.Unit")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("NExtLib.Unit")] +[assembly: AssemblyCopyright("Copyright © Mark Rendle 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ec152b00-d243-4378-9248-162d78b72a04")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.1.0.0")] +[assembly: AssemblyFileVersion("0.1.0.0")] diff --git a/Simple.NExtLib.Unit/ShouldExtensions.cs b/Simple.NExtLib.Unit/ShouldExtensions.cs new file mode 100644 index 00000000..ae1f23e5 --- /dev/null +++ b/Simple.NExtLib.Unit/ShouldExtensions.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NExtLib.TestExtensions; +using NUnit.Framework; + +namespace NExtLib.Unit +{ + public static class ShouldExtensions + { + public static void ShouldEqual(this T actual, T expected) + { + Assert.AreEqual(expected, actual); + } + + public static void ShouldEqual(this T actual, T expected, string message) + { + Assert.AreEqual(expected, actual, message); + } + + public static void ShouldBeNull(this T actual) + where T : class + { + Assert.IsNull(actual); + } + + public static void ShouldNotBeNull(this T actual) + where T : class + { + Assert.IsNotNull(actual); + } + + public static void Should(this T actual, IBinaryTest equal, T expected) + { + if (equal == null) throw new ArgumentNullException("equal"); + + equal.Run(expected, actual); + } + + public static void Should(this IEnumerable actual, IEnumerableTest test, T expected) + { + if (test == null) throw new ArgumentNullException("test"); + + test.RunTest(expected, actual); + } + } +} diff --git a/Simple.NExtLib.Unit/Simple.NExtLib.Unit.csproj b/Simple.NExtLib.Unit/Simple.NExtLib.Unit.csproj new file mode 100644 index 00000000..b21cf57a --- /dev/null +++ b/Simple.NExtLib.Unit/Simple.NExtLib.Unit.csproj @@ -0,0 +1,61 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {072F8BE4-81C1-4276-A9A5-1AEC87A84265} + Library + Properties + Simple.NExtLib.Unit + Simple.NExtLib.Unit + v4.0 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Simple.NExtLib.Unit/TestBase.cs b/Simple.NExtLib.Unit/TestBase.cs new file mode 100644 index 00000000..359d9a8d --- /dev/null +++ b/Simple.NExtLib.Unit/TestBase.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NExtLib.TestExtensions +{ + public abstract class TestBase + { + protected static readonly IBinaryTest Equal = new EqualTest(); + protected static readonly IEnumerableTest Contain = new ContainTest(); + } +} diff --git a/Simple.NExtLib/Async/AsyncException.cs b/Simple.NExtLib/Async/AsyncException.cs new file mode 100644 index 00000000..a93cbac6 --- /dev/null +++ b/Simple.NExtLib/Async/AsyncException.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Simple.NExtLib.Async +{ + [Serializable] + public class AsyncException : Exception + { + public AsyncException() { } + public AsyncException(string message) : base(message) { } + public AsyncException(string message, Exception inner) : base(message, inner) { } + protected AsyncException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) + : base(info, context) { } + } +} diff --git a/Simple.NExtLib/Async/Future.cs b/Simple.NExtLib/Async/Future.cs new file mode 100644 index 00000000..0ec066cb --- /dev/null +++ b/Simple.NExtLib/Async/Future.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Simple.NExtLib.Async; + +namespace Simple.NExtLib.Async +{ + public static class Future + { + /// + /// Creates an instance of . + /// + /// The type of value represented by the Future. + /// The delegate that will return the value. + /// A new instance of . + /// This method exists only to provide type-inference convenience. + public static Future Create(Func func) + { + return new Future(func); + } + } +} diff --git a/Simple.NExtLib/Async/Future`1.cs b/Simple.NExtLib/Async/Future`1.cs new file mode 100644 index 00000000..25b94349 --- /dev/null +++ b/Simple.NExtLib/Async/Future`1.cs @@ -0,0 +1,63 @@ +using System; + +namespace Simple.NExtLib.Async +{ + public class Future + { + private readonly Action _action; + private readonly IAsyncResult _asyncResult; + private readonly object _lock = new object(); + private bool _ended; + private T _value; + private Exception _error; + + public Future(Func func) + { + if (func == null) throw new ArgumentNullException("func"); + + _action = () => Run(func); + _asyncResult = _action.BeginInvoke(null, null); + } + + public T Value + { + get + { + JoinAction(); + + if (_error != null) throw new AsyncException(Properties.Resources.Async_AsyncExceptionMessage, _error); + return _value; + } + } + + private void Run(Func func) + { + try + { + _value = func(); + } + catch (Exception ex) + { + if (ex is SystemException) throw; + + _error = ex; + _value = default(T); + } + } + + private void JoinAction() + { + if (!_ended) + { + lock (_lock) + { + if (!_ended) + { + _action.EndInvoke(_asyncResult); + _ended = true; + } + } + } + } + } +} diff --git a/Simple.NExtLib/DateTimeExtensions.cs b/Simple.NExtLib/DateTimeExtensions.cs new file mode 100644 index 00000000..0a7b5689 --- /dev/null +++ b/Simple.NExtLib/DateTimeExtensions.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Simple.NExtLib +{ + public static class DateTimeExtensions + { + /// + /// Formats the DateTime to the ISO 8601 standard, to maximum precision. + /// + /// The date time. + /// String formatted like "2008-10-01T15:25:05.2852025Z" + public static string ToIso8601String(this DateTime dateTime) + { + return dateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); + } + } +} diff --git a/Simple.NExtLib/Func.cs b/Simple.NExtLib/Func.cs new file mode 100644 index 00000000..517a2a29 --- /dev/null +++ b/Simple.NExtLib/Func.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Simple.NExtLib +{ + public static class Func + { + public static Func NoOp() + where TIn : TOut + { + return (x) => x; + } + } +} diff --git a/Simple.NExtLib/IO/QuickIO.cs b/Simple.NExtLib/IO/QuickIO.cs new file mode 100644 index 00000000..66539497 --- /dev/null +++ b/Simple.NExtLib/IO/QuickIO.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace Simple.NExtLib.IO +{ + public static class QuickIO + { + public static string StreamToString(Stream stream) + { + string result; + + using (var reader = new StreamReader(stream)) + { + result = reader.ReadToEnd(); + } + + return result; + } + + public static Stream StringToStream(string str) + { + return new MemoryStream(Encoding.UTF8.GetBytes(str)); + } + } +} diff --git a/Simple.NExtLib/Linq/EnumerableExtensions.cs b/Simple.NExtLib/Linq/EnumerableExtensions.cs new file mode 100644 index 00000000..a6ac49c7 --- /dev/null +++ b/Simple.NExtLib/Linq/EnumerableExtensions.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Simple.NExtLib.Linq +{ + public static class EnumerableExtensions + { + public static IEnumerable> WithIndex(this IEnumerable source) + { + int index = 0; + return source.Select(item => Tuple.Create(item, index++)); + } + + public static IEnumerable OrIfEmpty(this IEnumerable source, IEnumerable alternate) + { + return source.Any() ? source : alternate; + } + } +} diff --git a/Simple.NExtLib/Linq/EnumerableOfKeyValuePairExtensions.cs b/Simple.NExtLib/Linq/EnumerableOfKeyValuePairExtensions.cs new file mode 100644 index 00000000..3977b569 --- /dev/null +++ b/Simple.NExtLib/Linq/EnumerableOfKeyValuePairExtensions.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace System.Linq +{ + public static class EnumerableOfKeyValuePairExtensions + { + public static Dictionary ToDictionary(this IEnumerable> source) + { + Dictionary dictionary; + + if ((dictionary = source as Dictionary) == null) + { + dictionary = source.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + } + + return dictionary; + } + + public static IDictionary ToIDictionary(this IEnumerable> source) + { + Dictionary dictionary; + + if ((dictionary = source as Dictionary) == null) + { + dictionary = source.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + } + + return dictionary; + } + } +} diff --git a/Simple.NExtLib/Linq/TupleEnumerableExtensions.cs b/Simple.NExtLib/Linq/TupleEnumerableExtensions.cs new file mode 100644 index 00000000..cd6bdf4d --- /dev/null +++ b/Simple.NExtLib/Linq/TupleEnumerableExtensions.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Simple.NExtLib.Linq +{ + public static class TupleEnumerableExtensions + { + public static bool Any(this IEnumerable> source, + Func predicate) + { + return source.Any(tuple => predicate(tuple.Item1, tuple.Item2)); + } + + public static bool All(this IEnumerable> source, + Func predicate) + { + return source.All(tuple => predicate(tuple.Item1, tuple.Item2)); + } + + public static int Count(this IEnumerable> source, + Func predicate) + { + return source.Count(tuple => predicate(tuple.Item1, tuple.Item2)); + } + + public static long LongCount(this IEnumerable> source, + Func predicate) + { + return source.LongCount(tuple => predicate(tuple.Item1, tuple.Item2)); + } + + public static Tuple First(this IEnumerable> source, + Func predicate) + { + return source.First(tuple => predicate(tuple.Item1, tuple.Item2)); + } + + public static Tuple FirstOrDefault(this IEnumerable> source, + Func predicate) + { + return source.FirstOrDefault(tuple => predicate(tuple.Item1, tuple.Item2)); + } + + public static Tuple Last(this IEnumerable> source, + Func predicate) + { + return source.Last(tuple => predicate(tuple.Item1, tuple.Item2)); + } + + public static Tuple LastOrDefault(this IEnumerable> source, + Func predicate) + { + return source.LastOrDefault(tuple => predicate(tuple.Item1, tuple.Item2)); + } + + public static IEnumerable Select(this IEnumerable> source, + Func selector) + { + return source.Select(tuple => selector(tuple.Item1, tuple.Item2)); + } + + public static IEnumerable SelectMany(this IEnumerable> source, + Func> selector) + { + return source.SelectMany(tuple => selector(tuple.Item1, tuple.Item2)); + } + + public static Tuple Single(this IEnumerable> source, + Func predicate) + { + return source.Single(tuple => predicate(tuple.Item1, tuple.Item2)); + } + + public static Tuple SingleOrDefault(this IEnumerable> source, + Func predicate) + { + return source.SingleOrDefault(tuple => predicate(tuple.Item1, tuple.Item2)); + } + } +} diff --git a/Simple.NExtLib/Properties/AssemblyInfo.cs b/Simple.NExtLib/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..86ade2ff --- /dev/null +++ b/Simple.NExtLib/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("NExtLib")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("NExtLib")] +[assembly: AssemblyCopyright("Copyright © Mark Rendle 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4ad3854e-d691-4546-9bf7-637fcbf035dc")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.1.0.0")] +[assembly: AssemblyFileVersion("0.1.0.0")] diff --git a/Simple.NExtLib/Properties/Resources.Designer.cs b/Simple.NExtLib/Properties/Resources.Designer.cs new file mode 100644 index 00000000..2d331b26 --- /dev/null +++ b/Simple.NExtLib/Properties/Resources.Designer.cs @@ -0,0 +1,72 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.1 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Simple.NExtLib.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Simple.NExtLib.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to An error occurred during execution.. + /// + internal static string Async_AsyncExceptionMessage { + get { + return ResourceManager.GetString("Async_AsyncExceptionMessage", resourceCulture); + } + } + } +} diff --git a/Simple.NExtLib/Properties/Resources.resx b/Simple.NExtLib/Properties/Resources.resx new file mode 100644 index 00000000..09c4560a --- /dev/null +++ b/Simple.NExtLib/Properties/Resources.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + An error occurred during execution. + + \ No newline at end of file diff --git a/Simple.NExtLib/Simple.NExtLib.csproj b/Simple.NExtLib/Simple.NExtLib.csproj new file mode 100644 index 00000000..ad56084f --- /dev/null +++ b/Simple.NExtLib/Simple.NExtLib.csproj @@ -0,0 +1,86 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {4A191FAD-DC1D-46FC-A941-7DEB2C8C4C15} + Library + Properties + Simple.NExtLib + Simple.NExtLib + v4.0 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + + + + \ No newline at end of file diff --git a/Simple.NExtLib/StringExtensions.cs b/Simple.NExtLib/StringExtensions.cs new file mode 100644 index 00000000..df09f675 --- /dev/null +++ b/Simple.NExtLib/StringExtensions.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Simple.NExtLib +{ + public static class StringExtensions + { + public static string EnsureStartsWith(this string source, string value) + { + return (source == null || source.StartsWith(value)) ? source : value + source; + } + } +} diff --git a/Simple.NExtLib/TupleExtensions.cs b/Simple.NExtLib/TupleExtensions.cs new file mode 100644 index 00000000..c0ded099 --- /dev/null +++ b/Simple.NExtLib/TupleExtensions.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Simple.NExtLib +{ + public static class TupleExtensions + { + public static void Run(this Tuple tuple, Action action) + { + action(tuple.Item1, tuple.Item2); + } + + public static void IfGood(this Tuple tuple, Action action) + { + if (tuple.Item1) + { + action(tuple.Item2); + } + } + } +} diff --git a/Simple.NExtLib/Xml/Linq/XAttributeExtensions.cs b/Simple.NExtLib/Xml/Linq/XAttributeExtensions.cs new file mode 100644 index 00000000..b7cc4e72 --- /dev/null +++ b/Simple.NExtLib/Xml/Linq/XAttributeExtensions.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace System.Xml.Linq +{ + public static class XAttributeExtensions + { + /// + /// Returns the string value of the Attribute or null if the attribute is null. + /// Null-safe, eliminates need for null-checking. + /// + /// The attribute. + /// + public static string ValueOrDefault(this XAttribute attribute) + { + return attribute != null ? attribute.Value : null; + } + } +} diff --git a/Simple.NExtLib/Xml/Linq/XElementExtensions.cs b/Simple.NExtLib/Xml/Linq/XElementExtensions.cs new file mode 100644 index 00000000..9ecbc70c --- /dev/null +++ b/Simple.NExtLib/Xml/Linq/XElementExtensions.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace System.Xml.Linq +{ + /// + /// Extension methods for . + /// + public static class XElementExtensions + { + public static XElement Element(this XElement element, string prefix, string name) + { + return Elements(element, prefix, name).FirstOrDefault(); + } + + public static IEnumerable Elements(this XElement element, string prefix, string name) + { + if (string.IsNullOrEmpty(prefix)) + { + return element.Elements().Where( + x => x.Name.LocalName == name && element.GetPrefixOfNamespace(x.Name.Namespace) == null); + } + + return element.Elements(ResolvePrefix(element, prefix) + name); + } + + public static IEnumerable Descendants(this XElement element, string prefix, string name) + { + var result = element.Descendants(ResolvePrefix(element, prefix) + name); + + if (result.Any()) return result; + + if (string.IsNullOrEmpty(prefix)) + { + return element.Descendants().Where( + x => x.Name.LocalName == name && element.GetPrefixOfNamespace(x.Name.Namespace) == null); + } + + return XElement.EmptySequence; + } + + public static XAttribute Attribute(this XElement element, string prefix, string name) + { + return element.Attribute(ResolvePrefix(element, prefix) + name); + } + + private static XNamespace ResolvePrefix(XElement element, string prefix) + { + return string.IsNullOrEmpty(prefix) ? element.GetDefaultNamespace() : element.GetNamespaceOfPrefix(prefix); + } + + public static string ValueOrDefault(this XElement element) + { + return element == null ? string.Empty : element.Value; + } + } +} diff --git a/Simple.NExtLib/Xml/Syndication/SyndicationItemExtensions.cs b/Simple.NExtLib/Xml/Syndication/SyndicationItemExtensions.cs new file mode 100644 index 00000000..5f88467a --- /dev/null +++ b/Simple.NExtLib/Xml/Syndication/SyndicationItemExtensions.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; +using System.ServiceModel.Syndication; + +namespace Simple.NExtLib.Xml.Syndication +{ + public static class SyndicationItemExtensions + { + public static XElement ContentAsXElement(this SyndicationItem item) + { + var content = item.Content as XmlSyndicationContent; + + if (content == null) return null; + + return XElement.ReadFrom(content.GetReaderAtContent()) as XElement; + } + + public static IEnumerable ContentsAsXElements(this SyndicationFeed feed) + { + XElement content; + + foreach (var item in feed.Items) + { + if ((content = item.ContentAsXElement()) != null) + { + yield return content; + } + } + } + } +} diff --git a/Simple.NExtLib/Xml/XElementAsDictionaryExtension.cs b/Simple.NExtLib/Xml/XElementAsDictionaryExtension.cs new file mode 100644 index 00000000..31170ad7 --- /dev/null +++ b/Simple.NExtLib/Xml/XElementAsDictionaryExtension.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; + +namespace Simple.NExtLib.Xml +{ + public static class XElementAsDictionaryExtension + { + public static XmlElementAsDictionary AsDictionary(this XElement element) + { + return new XmlElementAsDictionary(element); + } + + public static XName ResolveName(this XElement element, string name) + { + if (name.Contains(':')) + { + var bits = name.Split(':'); + if (bits.Length != 2) throw new ArgumentException("name"); + + var ns = element.GetNamespaceOfPrefix(bits[0]); + if (ns == null) throw new ArgumentException("name"); + + return ns + bits[1]; + } + else if (element.GetDefaultNamespace() != null) + { + return element.GetDefaultNamespace() + name; + } + else + { + return name; + } + } + + public static string FormatName(this XElement element, XName name) + { + if (name.Namespace == null) return name.LocalName; + if (name.Namespace == element.GetDefaultNamespace()) return name.LocalName; + string prefix = element.GetPrefixOfNamespace(name.Namespace); + if (!string.IsNullOrEmpty(prefix)) return prefix + ":" + name.LocalName; + return name.ToString(); + } + } +} diff --git a/Simple.NExtLib/Xml/XmlAttributesAsDictionary.cs b/Simple.NExtLib/Xml/XmlAttributesAsDictionary.cs new file mode 100644 index 00000000..8dd29b37 --- /dev/null +++ b/Simple.NExtLib/Xml/XmlAttributesAsDictionary.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; + +namespace Simple.NExtLib.Xml +{ + public class XmlAttributesAsDictionary + { + private readonly XElement _element; + + public XmlAttributesAsDictionary(XElement element) + { + _element = element; + } + + public string this[string name] + { + get + { + var attr = _element.Attribute(_element.ResolveName(name)) ?? _element.Attribute(name); + if (attr == null) return null; + return attr.Value; + } + + set + { + var xname = _element.ResolveName(name); + var attr = _element.Attribute(xname); + + if (attr == null) + { + _element.Add(new XAttribute(xname, value)); + } + else + { + attr.Value = value; + } + } + } + } +} diff --git a/Simple.NExtLib/Xml/XmlElementAsDictionary.cs b/Simple.NExtLib/Xml/XmlElementAsDictionary.cs new file mode 100644 index 00000000..77ffc82c --- /dev/null +++ b/Simple.NExtLib/Xml/XmlElementAsDictionary.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; +using System.IO; +using Simple.NExtLib.IO; +using Simple.NExtLib.Linq; + +namespace Simple.NExtLib.Xml +{ + public class XmlElementAsDictionary + { + private readonly XElement _element; + + public XmlElementAsDictionary(string name) + { + _element = new XElement(name); + } + + public XmlElementAsDictionary(string name, string defaultNamespace) + { + _element = XElement.Parse(string.Format(@"<{0} xmlns{1}=""{2}""/>", name, GetPrefixPart(name), defaultNamespace)); + } + + public XmlElementAsDictionary(XElement element) + { + _element = element; + } + + public XmlElementAsDictionary this[string name] + { + get + { + var xname = _element.ResolveName(name); + + return new XmlElementAsDictionary(_element.Element(xname) ?? CreateElement(xname)); + } + } + + public IEnumerable Keys + { + get { return _element.Elements().Select(element => _element.FormatName(element.Name)); } + } + + public string Value + { + get + { + return _element.Value; + } + set + { + _element.Value = value; + } + } + + public void Clear() + { + _element.RemoveAll(); + } + + public int Count + { + get { return _element.Elements().Count(); } + } + + private XElement CreateElement(XName name) + { + var element = new XElement(name); + _element.Add(element); + return element; + } + + public override string ToString() + { + return _element.ToString(); + } + + public void AddPrefixedNamespace(string prefix, string @namespace) + { + _element.Add(new XAttribute(XNamespace.Xmlns + prefix, @namespace)); + } + + public XmlAttributesAsDictionary Attributes + { + get { return new XmlAttributesAsDictionary(_element); } + } + + public XElement ToElement() + { + return new XElement(_element); + } + + public XDocument ToDocument() + { + return new XDocument(_element); + } + + public XDocument ToDocument(XDeclaration declaration) + { + return new XDocument(declaration, _element); + } + + public bool ContainsKey(string name) + { + return ContainsKey(_element.ResolveName(name)); + } + + private bool ContainsKey(XName name) + { + return _element.Elements(name).Any(); + } + + public bool Remove(string name) + { + return Remove(_element.ResolveName(name)); + } + + private bool Remove(XName name) + { + var elementToRemove = _element.Element(name); + + if (elementToRemove == null) return false; + + elementToRemove.Remove(); + + return true; + } + + private static string GetPrefixPart(string name) + { + if (name.Contains(':')) + { + var bits = name.Split(':'); + if (bits.Length != 2) throw new ArgumentException("name"); + return ":" + bits[0]; + } + + return ""; + } + + public static XmlElementAsDictionary Parse(string text) + { + if (text == null) throw new ArgumentNullException("text"); + + return new XmlElementAsDictionary(XElement.Parse(text)); + } + + public static XmlElementAsDictionary Parse(Stream stream) + { + if (stream == null) throw new ArgumentNullException("stream"); + + return Parse(QuickIO.StreamToString(stream)); + } + + public static IEnumerable ParseDescendants(string text, string elementName) + { + var element = XElement.Parse(text); + var xname = element.ResolveName(elementName); + + return element.Descendants(xname) + .OrIfEmpty(element.Descendants(elementName)) + .Select(e => new XmlElementAsDictionary(e)); + } + } +}