diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..3f7458e Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 44c4c21..ec4a96b 100644 --- a/.gitignore +++ b/.gitignore @@ -47,4 +47,6 @@ src/Common.Logging.Log4Net129/Common.Logging.Log4Net129.xml src/Common.Logging.Log4Net1211/Common.Logging.Log4Net1211.xml src/Common.Logging.NLog10/Common.Logging.NLog10.xml src/Common.Logging.NLog20/Common.Logging.NLog20.xml -src/Common.Logging/Common.Logging.xml \ No newline at end of file +src/Common.Logging/Common.Logging.xml + +test/Common.Logging.Tests/test-results/Common.Logging.Tests.2010.csproj-Debug-2013-07-14.xml diff --git a/Common.Logging.2010-net40.userprefs b/Common.Logging.2010-net40.userprefs new file mode 100644 index 0000000..5a2f86a --- /dev/null +++ b/Common.Logging.2010-net40.userprefs @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Common.Logging.MonoTouch.sln b/Common.Logging.MonoTouch.sln new file mode 100644 index 0000000..f726733 --- /dev/null +++ b/Common.Logging.MonoTouch.sln @@ -0,0 +1,74 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Logging.MonoTouch", "src\Common.Logging.MonoTouch\Common.Logging.MonoTouch.csproj", "{C5FED159-541C-4245-95CA-661C4E29A2DD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Logging.TestUtils.MonoTouch", "src\Common.Logging.MonoTouch\Common.Logging.TestUtils.MonoTouch\Common.Logging.TestUtils.MonoTouch.csproj", "{B928FD65-4E80-4F9D-96D0-830EDB3092DB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Logging.MonoTouch.Tests", "src\Common.Logging.MonoTouch\Common.Logging.MonoTouch.Tests\Common.Logging.MonoTouch.Tests.csproj", "{04F451AA-0CEE-4971-AC7E-9D401114F1E2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + Debug|iPhoneSimulator = Debug|iPhoneSimulator + Release|iPhoneSimulator = Release|iPhoneSimulator + Debug|iPhone = Debug|iPhone + Release|iPhone = Release|iPhone + Ad-Hoc|iPhone = Ad-Hoc|iPhone + AppStore|iPhone = AppStore|iPhone + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.AppStore|iPhone.ActiveCfg = AppStore|iPhone + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.AppStore|iPhone.Build.0 = AppStore|iPhone + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Debug|iPhone.ActiveCfg = Debug|iPhone + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Debug|iPhone.Build.0 = Debug|iPhone + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Release|Any CPU.Build.0 = Release|iPhoneSimulator + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Release|iPhone.ActiveCfg = Release|iPhone + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Release|iPhone.Build.0 = Release|iPhone + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator + {04F451AA-0CEE-4971-AC7E-9D401114F1E2}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.AppStore|iPhone.Build.0 = Debug|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Debug|iPhone.Build.0 = Debug|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Release|Any CPU.Build.0 = Release|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Release|iPhone.ActiveCfg = Release|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Release|iPhone.Build.0 = Release|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {B928FD65-4E80-4F9D-96D0-830EDB3092DB}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.AppStore|iPhone.Build.0 = Debug|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Debug|iPhone.Build.0 = Debug|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Release|Any CPU.Build.0 = Release|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Release|iPhone.ActiveCfg = Release|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Release|iPhone.Build.0 = Release|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {C5FED159-541C-4245-95CA-661C4E29A2DD}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = src\Common.Logging.MonoTouch\Common.Logging.MonoTouch.csproj + EndGlobalSection +EndGlobal diff --git a/Common.Logging.MonoTouch.userprefs b/Common.Logging.MonoTouch.userprefs new file mode 100644 index 0000000..b7be76a --- /dev/null +++ b/Common.Logging.MonoTouch.userprefs @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000..7fbaf2e Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/Common.Logging.MonoTouch/.DS_Store b/src/Common.Logging.MonoTouch/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/src/Common.Logging.MonoTouch/.DS_Store differ diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/AssemblyInfo.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/AssemblyInfo.cs new file mode 100644 index 0000000..1c11957 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; + +// +// 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("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// 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 Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Common.Logging.MonoTouch.Tests.csproj b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Common.Logging.MonoTouch.Tests.csproj new file mode 100644 index 0000000..ff75b0e --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Common.Logging.MonoTouch.Tests.csproj @@ -0,0 +1,128 @@ + + + + Debug + iPhoneSimulator + 10.0.0 + 2.0 + {04F451AA-0CEE-4971-AC7E-9D401114F1E2} + {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Exe + Common.Logging.MonoTouch.Tests + Resources + CommonLoggingMonoTouchTests + + + True + full + False + bin\iPhoneSimulator\Debug + DEBUG; + prompt + 4 + False + True + True + None + + + none + True + bin\iPhoneSimulator\Release + prompt + 4 + False + None + + + True + full + False + bin\iPhone\Debug + DEBUG; + prompt + 4 + False + iPhone Developer + True + True + + + none + True + bin\iPhone\Release + prompt + 4 + False + iPhone Developer + + + none + True + bin\iPhone\Ad-Hoc + prompt + 4 + True + False + Automatic:AdHoc + iPhone Distribution + + + none + True + bin\iPhone\AppStore + prompt + 4 + False + iPhone Distribution + Automatic:AppStore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {C5FED159-541C-4245-95CA-661C4E29A2DD} + Common.Logging.MonoTouch + + + {B928FD65-4E80-4F9D-96D0-830EDB3092DB} + Common.Logging.TestUtils.MonoTouch + + + \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/ExceptionsTest.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/ExceptionsTest.cs new file mode 100644 index 0000000..f4affbc --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/ExceptionsTest.cs @@ -0,0 +1,450 @@ +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.IO; +using System.Reflection; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using NUnit.Framework; + +#endregion + +namespace Common +{ + /// + /// Tests the various exception classes. + /// + /// + /// + /// Shamelessly lifted from the NAnt test suite. + /// + /// + /// Rick Evans + /// $Id:$ + public abstract class ExceptionsTest : StandardsComplianceTest + { + protected ExceptionsTest() + { + CheckedType = typeof (Exception); + } + + #region Tests + + [Test] + public void TestStandardsCompliance() + { + ProcessAssembly(AssemblyToCheck); + } + + [Test] + public void TestThisTest() + { + ProcessAssembly(Assembly.GetAssembly(GetType())); + } + + #endregion + + #region Methods + + protected override void CheckStandardsCompliance(Assembly assembly, Type t) + { + // check to see that the exception is correctly named, with "Exception" at the end + bool nameIsValid = t.Name.EndsWith("Exception"); + Assert.IsTrue(nameIsValid, t.Name + " class name must end with Exception."); + if (t.IsAbstract) + { + return; + } + // Does the exception have the 3 standard constructors? + // Default constructor + CheckPublicConstructor(t, "()"); + // Constructor with a single string parameter + CheckPublicConstructor(t, "(string message)", typeof (String)); + // Constructor with a string and an inner exception + CheckPublicConstructor(t, "(string message, Exception inner)", + typeof (String), typeof (Exception)); + // check to see if the serialization constructor is present + // if exception is sealed, constructor should be private + // if exception is not sealed, constructor should be protected + if (t.IsSealed) + { + // check to see if the private serialization constructor is present... + CheckPrivateConstructor(t, "(SerializationInfo info, StreamingContext context)", + typeof (SerializationInfo), + typeof (StreamingContext)); + } + else + { + // check to see if the protected serialization constructor is present... + CheckProtectedConstructor(t, "(SerializationInfo info, StreamingContext context)", + typeof (SerializationInfo), + typeof (StreamingContext)); + } + // check to see if the type is marked as serializable + Assert.IsTrue(t.IsSerializable, t.Name + " is not serializable, missing [Serializable]?"); + // check to see if there are any public fields. These should be properties instead... + FieldInfo[] publicFields = + t.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance); + if (publicFields.Length != 0) + { + foreach (FieldInfo fieldInfo in publicFields) + { + Assert.Fail(t.Name + "." + fieldInfo.Name + + " is a public field, should be exposed through property instead."); + } + } + // If this exception has any fields, check to make sure it has a + // version of GetObjectData. If not, it does't serialize those fields. + FieldInfo[] fields = + t.GetFields(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public | + BindingFlags.Instance); + if (fields.Length != 0) + { + if ( + t.GetMethod("GetObjectData", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance) == + null) + { + Assert.Fail(t.Name + " does not implement GetObjectData but has private fields."); + } + } + if (!t.IsAbstract) + { + CheckInstantiation(t); + } + } + + /// + /// Checks the public constructor. + /// + /// The type + /// The description. + /// The parameters. + private void CheckPublicConstructor(Type t, string description, params Type[] parameters) + { + // locate constructor + ConstructorInfo ci = + t.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, parameters, + null); + // fail if constructor does not exist + Assert.IsNotNull(ci, t.Name + description + " is a required constructor."); + // fail if constructor is private + Assert.IsFalse(ci.IsPrivate, t.Name + description + " is private, must be public."); + // fail if constructor is protected + Assert.IsFalse(ci.IsFamily, t.Name + description + " is internal, must be public."); + // fail if constructor is internal + Assert.IsFalse(ci.IsAssembly, t.Name + description + " is internal, must be public."); + // fail if constructor is protected internal + Assert.IsFalse(ci.IsFamilyOrAssembly, t.Name + description + " is protected internal, must be public."); + // sanity check to make sure the constructor is public + Assert.IsTrue(ci.IsPublic, t.Name + description + " is not public, must be public."); + } + + private void CheckProtectedConstructor(Type t, string description, params Type[] parameters) + { + // locate constructor + ConstructorInfo ci = + t.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, parameters, + null); + // fail if constructor does not exist + Assert.IsNotNull(ci, t.Name + description + " is a required constructor."); + // fail if constructor is public + Assert.IsFalse(ci.IsPublic, t.Name + description + " is public, must be protected."); + // fail if constructor is private + Assert.IsFalse(ci.IsPrivate, t.Name + description + " is private, must be public or protected."); + // fail if constructor is internal + Assert.IsFalse(ci.IsAssembly, t.Name + description + " is internal, must be protected."); + // fail if constructor is protected internal + Assert.IsFalse(ci.IsFamilyOrAssembly, t.Name + description + " is protected internal, must be protected."); + // sanity check to make sure the constructor is protected + Assert.IsTrue(ci.IsFamily, t.Name + description + " is not protected, must be protected."); + } + + private void CheckPrivateConstructor(Type t, string description, params Type[] parameters) + { + // locate constructor + ConstructorInfo ci = + t.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, parameters, + null); + // fail if constructor does not exist + Assert.IsNotNull(ci, t.Name + description + " is a required constructor."); + // fail if constructor is public + Assert.IsFalse(ci.IsPublic, t.Name + description + " is public, must be private."); + // fail if constructor is protected + Assert.IsFalse(ci.IsFamily, t.Name + description + " is protected, must be private."); + // fail if constructor is internal + Assert.IsFalse(ci.IsAssembly, t.Name + description + " is internal, must be private."); + // fail if constructor is protected internal + Assert.IsFalse(ci.IsFamilyOrAssembly, t.Name + description + " is protected internal, must be private."); + // sanity check to make sure the constructor is private + Assert.IsTrue(ci.IsPrivate, t.Name + description + " is not private, must be private."); + } + + /// + /// If we've got here, then the standards compliance tests have passed... + /// + /// The exception type being tested. + private void CheckInstantiation(Type t) + { + // attempt to instantiate the 3 standard ctors... + ConstructorInfo ctor = t.GetConstructor(Type.EmptyTypes); + try + { + ctor.Invoke(null); + } + catch (Exception ex) + { + Assert.Fail("Ctor () for '" + t.Name + "' threw an exception : " + ex.Message); + } + ctor = t.GetConstructor(new Type[] {typeof (string)}); + try + { + Exception ex = (Exception) ctor.Invoke(new object[] {"My Fingers Turn To Fists"}); + Assert.IsNotNull(ex.Message, t.Name + "'s Message was null."); + } + catch (Exception ex) + { + Assert.Fail("Ctor (string) for '" + t.Name + "' threw an exception : " + ex.Message); + } + ctor = t.GetConstructor(new Type[] {typeof (string), typeof (Exception)}); + try + { + Exception ex = + (Exception) ctor.Invoke(new object[] {"My Fingers Turn To Fists", new FormatException("Bing")}); + Assert.IsNotNull(ex.Message, t.Name + "'s Message was null."); + Assert.IsNotNull(ex.InnerException, t.Name + "'s InnerException was null."); + Assert.AreEqual("Bing", ex.InnerException.Message); + } + catch (Exception ex) + { + Assert.Fail("Ctor (string, Exception) for '" + t.Name + "' threw an exception : " + ex.Message); + } + // test the serialization ctor + try + { + ctor = t.GetConstructor(new Type[] {typeof (string)}); + Exception ex = (Exception) ctor.Invoke(new object[] {"HungerHurtsButStarvingWorks"}); + BinaryFormatter bf = new BinaryFormatter(); + MemoryStream ms = new MemoryStream(); + bf.Serialize(ms, ex); + ms.Seek(0, 0); + Exception inex = (Exception) bf.Deserialize(ms); + Assert.IsNotNull(inex); + } + catch (Exception ex) + { + Assert.Fail("Ctor (Serialization) for '" + t.Name + "' threw an exception : " + ex.Message); + } + } + + #endregion + + #region Properties + + /// + /// We will test all of the exceptions in this assembly for their correctness. + /// + protected Assembly AssemblyToCheck + { + get { return _assemblyToCheck; } + set { _assemblyToCheck = value; } + } + + #endregion + + private Assembly _assemblyToCheck = null; + } + + #region Inner Class : SimpleTestException + + /// + /// Do nothing exception to verify that the exception tester + /// is working correctly. + /// + [Serializable] + public class SimpleTestException : ApplicationException + { + #region Public Instance Constructors + + public SimpleTestException() + { + } + + public SimpleTestException(string message) : base(message) + { + } + + public SimpleTestException(string message, Exception inner) + : base(message, inner) + { + } + + #endregion Public Instance Constructors + + #region Protected Instance Constructors + + // deserialization constructor + protected SimpleTestException( + SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + #endregion Protected Instance Constructors + } + + #endregion + + #region Inner Class : TestException + + /// + /// Exception to verify that the exception tester is working correctly. + /// + [Serializable] + public class TestException : ApplicationException, ISerializable + { + #region Private Instance Fields + + private int _value; + + #endregion Private Instance Fields + + #region Public Instance Constructors + + public TestException() + { + } + + public TestException(string message) : base(message) + { + } + + public TestException(string message, Exception inner) + : base(message, inner) + { + } + + // constructors that take the added value + public TestException(string message, int value) : base(message) + { + _value = value; + } + + #endregion Public Instance Constructors + + #region Protected Instance Constructors + + // deserialization constructor + protected TestException(SerializationInfo info, StreamingContext context) : base(info, context) + { + _value = info.GetInt32("Value"); + } + + #endregion Protected Instance Constructors + + #region Public Instance Properties + + public int Value + { + get { return _value; } + } + + #endregion Public Instance Properties + + #region Override implementation of ApplicationException + + // Called by the frameworks during serialization + // to fetch the data from an object. + public override void GetObjectData( + SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + info.AddValue("Value", _value); + } + + // overridden Message property. This will give the + // proper textual representation of the exception, + // with the added field value. + public override string Message + { + get + { + // NOTE: should be localized... + string s = + string.Format( + CultureInfo.InvariantCulture, "Value: {0}", _value); + return base.Message + Environment.NewLine + s; + } + } + + #endregion Override implementation of ApplicationException + } + + #endregion + + #region Inner Class : SealedTestException + + /// + /// Exception to verify that the exception tester is working on + /// sealed exception. + /// + [Serializable] + public sealed class SealedTestException : TestException + { + #region Public Instance Constructors + + public SealedTestException() + { + } + + public SealedTestException(string message) : base(message) + { + } + + public SealedTestException(string message, Exception inner) + : base(message, inner) + { + } + + // constructors that take the added value + public SealedTestException(string message, int value) + : base(message, value) + { + } + + #endregion Public Instance Constructors + + #region Private Instance Constructors + + // deserialization constructor + private SealedTestException( + SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + #endregion Private Instance Constructors + } + + #endregion +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Info.plist b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Info.plist new file mode 100644 index 0000000..8653860 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Info.plist @@ -0,0 +1,26 @@ + + + + + UIDeviceFamily + + 1 + 2 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + MinimumOSVersion + 3.2 + + diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/Configuration/ArgUtilsTests.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/Configuration/ArgUtilsTests.cs new file mode 100644 index 0000000..61a70d6 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/Configuration/ArgUtilsTests.cs @@ -0,0 +1,158 @@ +#region License + +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System; +using System.Collections.Specialized; +using System.Runtime.Serialization; +using NUnit.Framework; + +namespace Common.Logging.Configuration +{ + /// + /// + /// Erich Eichinger + [TestFixture] + public class ArgUtilsTests + { + [Test] + public void GetValue() + { + NameValueCollection nvc = new NameValueCollection(); + nvc["key"] = "value"; + + Assert.AreEqual( null, ArgUtils.GetValue(null, "key")); + Assert.AreEqual("value", ArgUtils.GetValue(nvc, "key")); + Assert.AreEqual(null, ArgUtils.GetValue(nvc, "wrongkey")); + Assert.AreEqual("defaultValue", ArgUtils.GetValue(null, "wrongkey", "defaultValue")); + Assert.AreEqual("defaultValue", ArgUtils.GetValue(nvc, "wrongkey", "defaultValue")); + } + + [Test] + public void Coalesce() + { + Assert.AreEqual(null, ArgUtils.Coalesce()); + Assert.AreEqual(null, ArgUtils.Coalesce(null, null)); + Assert.AreEqual("x", ArgUtils.Coalesce(string.Empty, null, "x")); + // null predicate causes the use the default predicate of (v!=null) + Assert.AreEqual(string.Empty, ArgUtils.Coalesce( (Predicate)null, string.Empty, (string)null, "x")); + Assert.AreEqual(null, ArgUtils.Coalesce( delegate(object v) { return v != null; } )); + Assert.AreEqual(string.Empty, ArgUtils.Coalesce( delegate(object v) { return v != null; }, null, string.Empty, "x")); + } + + [Test] + public void TryParseEnum() + { + Assert.Throws( + Is.TypeOf().And.Message.EqualTo( string.Format("Type '{0}' is not an enum type", typeof(int).FullName) ) + , delegate + { + ArgUtils.TryParseEnum((int) 1, "0"); + } + ); + + Assert.AreEqual( LogLevel.Fatal, ArgUtils.TryParseEnum(LogLevel.All, "fatal") ); + Assert.AreEqual( LogLevel.Debug, ArgUtils.TryParseEnum(LogLevel.Debug, "invalid value") ); + Assert.AreEqual( LogLevel.Debug, ArgUtils.TryParseEnum(LogLevel.Debug, null) ); + } + + [Test] + public void TryParse() + { + Assert.Throws( + Is.TypeOf() + .And.Message.EqualTo(string.Format("There is no parser registered for type {0}", typeof(object).FullName)) + , delegate + { + ArgUtils.TryParse(new object(), "0"); + } + ); + + Assert.AreEqual( true, ArgUtils.TryParse(false, "trUE") ); + Assert.AreEqual( 1, ArgUtils.TryParse(2, "1") ); + Assert.AreEqual( 2, ArgUtils.TryParse(2, "2invalidnumber1") ); + Assert.AreEqual( (short)1, ArgUtils.TryParse((short)2, "1") ); + Assert.AreEqual( (long)1, ArgUtils.TryParse((long)2, "1") ); + Assert.AreEqual( (float)1, ArgUtils.TryParse((float)2, "1") ); + Assert.AreEqual( (double)1, ArgUtils.TryParse((double)2, "1") ); + Assert.AreEqual( (decimal)1, ArgUtils.TryParse((decimal)2, "1") ); + } + + [Test] + public void AssertIsAssignable() + { + Assert.Throws( + Is.TypeOf() + .And.Message.EqualTo(new ArgumentNullException("valType").Message) + , delegate + { + ArgUtils.AssertIsAssignable("arg", null); + } + ); + + Assert.Throws( + Is.TypeOf() + .And.Message.EqualTo(new ArgumentOutOfRangeException("this", this.GetType(),string.Format("Type '{0}' of parameter '{1}' is not assignable to target type '{2}'" + , this.GetType().AssemblyQualifiedName + , "this" + , typeof (ISerializable).AssemblyQualifiedName) ).Message) + , delegate + { + ArgUtils.AssertIsAssignable("this", this.GetType()); + } + ); + + Type type = typeof(Int32); + Assert.AreSame(type, ArgUtils.AssertIsAssignable("arg", type)); + } + + [Test] + public void AssertNotNullThrowsArgumentNullException() + { + object tmp = new object(); + Assert.AreSame(tmp, ArgUtils.AssertNotNull("arg", tmp)); + Assert.Throws(Is.TypeOf() + .And.Message.EqualTo(new ArgumentNullException("tmp").Message), + delegate { ArgUtils.AssertNotNull("tmp", (object)null); }); + Assert.Throws(Is.TypeOf().And.Message.EqualTo(new ArgumentNullException("tmp", "message msgarg").Message), + delegate { ArgUtils.AssertNotNull("tmp", (object)null, "message {0}", "msgarg"); }); + } + + [Test] + public void Guard() + { + ArgUtils.Guard(delegate { }, "format {0}", "fmtarg"); + Assert.AreEqual(1, ArgUtils.Guard(delegate { return 1; }, "format {0}", "fmtarg")); + + Assert.Throws(Is.TypeOf() + .And.Message.EqualTo("innermessage"), + delegate + { + ArgUtils.Guard(delegate { throw new ConfigurationException("innermessage"); }, "format {0}", "fmtarg"); + }); + + Assert.Throws(Is.TypeOf() + .And.Message.EqualTo("format fmtarg"), + delegate + { + ArgUtils.Guard(delegate { throw new ArgumentException("innermessage"); }, "format {0}", "fmtarg"); + }); + } + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/Configuration/MonoTouchConfigurationReaderTests.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/Configuration/MonoTouchConfigurationReaderTests.cs new file mode 100644 index 0000000..e36b8e7 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/Configuration/MonoTouchConfigurationReaderTests.cs @@ -0,0 +1,38 @@ +#region License + +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System.Collections.Specialized; +using NUnit.Framework; +using Common.Logging.Simple; +namespace Common.Logging.Configuration +{ + /// + /// + /// Erich Eichinger + [TestFixture] + public class MonoTouchConfigurationReaderTests + { + [Test] + public void ReadsAppConfig() + { + Assert.IsNotNull(((ConsoleOutLoggerFactoryAdapter)new DefaultConfigurationReader().GetSection("Settings.bundle/Common.Logging.plist"))); + } + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/Factory/AbstractLoggerTests.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/Factory/AbstractLoggerTests.cs new file mode 100644 index 0000000..1f19f42 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/Factory/AbstractLoggerTests.cs @@ -0,0 +1,479 @@ +#region License + +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System; +using System.Collections; +using System.Globalization; +using System.Reflection; +using NUnit.Framework; +//using Rhino.Mocks; +//using Rhino.Mocks.Interfaces; +using FormatMessageCallback = System.Action; +//using Is=Rhino.Mocks.Constraints.Is; + +namespace Common.Logging.Factory +{ + /// + /// Tests for class. In particular ensures, that all ILog.XXX methods + /// correctuly route to the single WriteInternal delegate. + /// + [TestFixture] + public class AbstractLoggerTests + { + [Test] + public void IsSerializable() + { + SerializationTestUtils.IsSerializable(); + } + + [Test] + public void ImplementsAllMethodsForAllLevels() + { + string[] logLevels = Exclude(Enum.GetNames(typeof (LogLevel)), "All", "Off"); + + foreach (string logLevel in logLevels) + { + MethodInfo[] logMethods = GetLogMethodSignatures(logLevel); + for (int i = 0; i < logLevels.Length; i++) + { + Assert.IsNotNull(logMethods[i], + "Method with signature #{0} not implemented for level {1}", i, logLevel); + } + } + } + + [Test] + public void LogsMessage() + { + string[] logLevels = Exclude(Enum.GetNames(typeof(LogLevel)), "All", "Off"); + + foreach (string logLevel in logLevels) + { + LogsMessage(logLevel); + } + } + + /// + /// Ensures, that all interface methods delegate to Write() with correct level + arguments + /// and that arguments are still not evaluated up to this point (e.g. calling ToString()) + /// + private static void LogsMessage(string levelName) + { + //MockRepository mocks = new MockRepository(); + + TestLogger log = new TestLogger(); + Exception ex = new Exception(); + + + MethodInfo[] logMethods = GetLogMethodSignatures(levelName); + + LogLevel logLevel = (LogLevel)Enum.Parse(typeof(LogLevel), levelName); + + Invoke(log, logMethods[0], "messageObject0"); + Assert.AreEqual(logLevel, log.LastLogLevel); + Assert.AreEqual("messageObject0", log.LastMessage); + Assert.AreEqual(null, log.LastException); + + Invoke(log, logMethods[1], "messageObject1", ex); + Assert.AreEqual(logLevel, log.LastLogLevel); + Assert.AreEqual("messageObject1", log.LastMessage); + Assert.AreEqual(ex, log.LastException); + + Invoke(log, logMethods[2], "format2 {0}", new object[] { "arg2" }); + Assert.AreEqual(logLevel, log.LastLogLevel); + Assert.AreEqual("format2 arg2", log.LastMessage); + Assert.AreEqual(null, log.LastException); + + Invoke(log, logMethods[3], "format3 {0}", ex, new object[] { "arg3" }); + Assert.AreEqual(logLevel, log.LastLogLevel); + Assert.AreEqual("format3 arg3", log.LastMessage); + Assert.AreEqual(ex, log.LastException); + + Invoke(log, logMethods[4], CultureInfo.CreateSpecificCulture("de-de"), "format4 {0}", new object[] { 4.1 }); + Assert.AreEqual(logLevel, log.LastLogLevel); + Assert.AreEqual("format4 4,1", log.LastMessage); + Assert.AreEqual(null, log.LastException); + + Invoke(log, logMethods[5], CultureInfo.CreateSpecificCulture("de-de"), "format5 {0}", ex, new object[] { 5.1 }); + Assert.AreEqual(logLevel, log.LastLogLevel); + Assert.AreEqual("format5 5,1", log.LastMessage); + Assert.AreEqual(ex, log.LastException); + + Invoke(log, logMethods[6], TestFormatMessageCallback.MessageCallback("message6")); + Assert.AreEqual(logLevel, log.LastLogLevel); + Assert.AreEqual("message6", log.LastMessage); + Assert.AreEqual(null, log.LastException); + + Invoke(log, logMethods[7], TestFormatMessageCallback.MessageCallback("message7"), ex); + Assert.AreEqual(logLevel, log.LastLogLevel); + Assert.AreEqual("message7", log.LastMessage); + Assert.AreEqual(ex, log.LastException); + + Invoke(log, logMethods[8], CultureInfo.CreateSpecificCulture("de-de"), TestFormatMessageCallback.MessageCallback("format8 {0}", new object[] { 8.1 })); + Assert.AreEqual(logLevel, log.LastLogLevel); + Assert.AreEqual("format8 8,1", log.LastMessage); + Assert.AreEqual(null, log.LastException); + + Invoke(log, logMethods[9], CultureInfo.CreateSpecificCulture("de-de"), TestFormatMessageCallback.MessageCallback("format9 {0}", new object[] { 9.1 }), ex); + Assert.AreEqual(logLevel, log.LastLogLevel); + Assert.AreEqual("format9 9,1", log.LastMessage); + Assert.AreEqual(ex, log.LastException); + } + /* + [Test] + public void WriteIsCalledWithCorrectLogLevel() + { + string[] logLevels = Exclude(Enum.GetNames(typeof(LogLevel)), "All", "Off"); + + foreach (string logLevel in logLevels) + { + WriteIsCalledWithCorrectLogLevel(logLevel); + } + } + + /// + /// Ensures, that all interface methods delegate to Write() with correct level + arguments + /// and that arguments are still not evaluated up to this point (e.g. calling ToString()) + /// + private static void WriteIsCalledWithCorrectLogLevel(string levelName) + { + MockRepository mocks = new MockRepository(); + + AbstractTestLogger log = (AbstractTestLogger)mocks.PartialMock(typeof(AbstractTestLogger)); + Exception ex = (Exception)mocks.StrictMock(typeof(Exception)); + object messageObject = mocks.StrictMock(typeof(object)); + object formatArg = mocks.StrictMock(typeof(object)); + FormatMessageCallback failCallback = TestFormatMessageCallback.FailCallback(); + + MethodInfo[] logMethods = GetLogMethodSignatures(levelName); + + LogLevel logLevel = (LogLevel) Enum.Parse(typeof (LogLevel), levelName); + + using (mocks.Ordered()) + { + log.Log(logLevel, null, null); + LastCall.Constraints(Is.Equal(logLevel), Is.Anything(), Is.Null()); + log.Log(logLevel, null, ex); + LastCall.Constraints(Is.Equal(logLevel), Is.Anything(), Is.Same(ex)); + log.Log(logLevel, null, null); + LastCall.Constraints(Is.Equal(logLevel), Is.Anything(), Is.Null()); + log.Log(logLevel, null, ex); + LastCall.Constraints(Is.Equal(logLevel), Is.Anything(), Is.Same(ex)); + log.Log(logLevel, null, null); + LastCall.Constraints(Is.Equal(logLevel), Is.Anything(), Is.Null()); + log.Log(logLevel, null, ex); + LastCall.Constraints(Is.Equal(logLevel), Is.Anything(), Is.Same(ex)); + log.Log(logLevel, null, null); + LastCall.Constraints(Is.Equal(logLevel), Is.Anything(), Is.Null()); + log.Log(logLevel, null, ex); + LastCall.Constraints(Is.Equal(logLevel), Is.Anything(), Is.Same(ex)); + log.Log(logLevel, null, null); + LastCall.Constraints(Is.Equal(logLevel), Is.Anything(), Is.Null()); + log.Log(logLevel, null, ex); + LastCall.Constraints(Is.Equal(logLevel), Is.Anything(), Is.Same(ex)); + } + mocks.ReplayAll(); + + Invoke(log, logMethods[0], messageObject); + Invoke(log, logMethods[1], messageObject, ex); + Invoke(log, logMethods[2], "format", new object[] { formatArg }); + Invoke(log, logMethods[3], "format", ex, new object[] { formatArg }); + Invoke(log, logMethods[4], CultureInfo.InvariantCulture, "format", new object[] { formatArg }); + Invoke(log, logMethods[5], CultureInfo.InvariantCulture, "format", ex, new object[] { formatArg }); + Invoke(log, logMethods[6], failCallback); + Invoke(log, logMethods[7], failCallback, ex); + Invoke(log, logMethods[8], CultureInfo.InvariantCulture, failCallback); + Invoke(log, logMethods[9], CultureInfo.InvariantCulture, failCallback, ex); + + mocks.VerifyAll(); + } +*/ + /* + [Test] + public void WriteAndEvaluateOnlyWhenLevelEnabled() + { + string[] logLevels = Exclude(Enum.GetNames(typeof(LogLevel)), "All", "Off"); + + foreach (string logLevel in logLevels) + { + WriteAndEvaluateOnlyWhenLevelEnabled(logLevel); + } + } + + /// + /// This test ensures, that for a given loglevel + /// a) AbstractLogger.Write is not called if that loglevel is disabled + /// b) No argument is evaluated (e.g. calling ToString()) if that loglevel is disabled + /// + private static void WriteAndEvaluateOnlyWhenLevelEnabled(string levelName) + { + MockRepository mocks = new MockRepository(); + + AbstractLogger log = (AbstractLogger)mocks.StrictMock(typeof(AbstractLogger)); + Exception ex = (Exception)mocks.StrictMock(typeof(Exception)); + object messageObject = mocks.StrictMock(typeof(object)); + object formatArg = mocks.StrictMock(typeof(object)); + FormatMessageCallback failCallback = TestFormatMessageCallback.FailCallback(); + + MethodInfo[] logMethods = GetLogMethodSignatures(levelName); + + using (mocks.Ordered()) + { + Invoke(log, logMethods[0], messageObject); + LastCall.CallOriginalMethod(OriginalCallOptions.CreateExpectation); + Expect.Call(IsLevelEnabled(log, levelName)).Return(false); + Invoke(log, logMethods[1], messageObject, ex); + LastCall.CallOriginalMethod(OriginalCallOptions.CreateExpectation); + Expect.Call(IsLevelEnabled(log, levelName)).Return(false); + Invoke(log, logMethods[2], "format", new object[] { formatArg }); + LastCall.CallOriginalMethod(OriginalCallOptions.CreateExpectation); + Expect.Call(IsLevelEnabled(log, levelName)).Return(false); + Invoke(log, logMethods[3], "format", ex, new object[] { formatArg }); + LastCall.CallOriginalMethod(OriginalCallOptions.CreateExpectation); + Expect.Call(IsLevelEnabled(log, levelName)).Return(false); + Invoke(log, logMethods[4], CultureInfo.InvariantCulture, "format", new object[] { formatArg }); + LastCall.CallOriginalMethod(OriginalCallOptions.CreateExpectation); + Expect.Call(IsLevelEnabled(log, levelName)).Return(false); + Invoke(log, logMethods[5], CultureInfo.InvariantCulture, "format", ex, new object[] { formatArg }); + LastCall.CallOriginalMethod(OriginalCallOptions.CreateExpectation); + Expect.Call(IsLevelEnabled(log, levelName)).Return(false); + Invoke(log, logMethods[6], failCallback); + LastCall.CallOriginalMethod(OriginalCallOptions.CreateExpectation); + Expect.Call(IsLevelEnabled(log, levelName)).Return(false); + Invoke(log, logMethods[7], failCallback, ex); + LastCall.CallOriginalMethod(OriginalCallOptions.CreateExpectation); + Expect.Call(IsLevelEnabled(log, levelName)).Return(false); + Invoke(log, logMethods[8], CultureInfo.InvariantCulture, failCallback); + LastCall.CallOriginalMethod(OriginalCallOptions.CreateExpectation); + Expect.Call(IsLevelEnabled(log, levelName)).Return(false); + Invoke(log, logMethods[9], CultureInfo.InvariantCulture, failCallback, ex); + LastCall.CallOriginalMethod(OriginalCallOptions.CreateExpectation); + Expect.Call(IsLevelEnabled(log, levelName)).Return(false); + } + mocks.ReplayAll(); + + Invoke(log, logMethods[0], messageObject); + Invoke(log, logMethods[1], messageObject, ex); + Invoke(log, logMethods[2], "format", new object[] {formatArg}); + Invoke(log, logMethods[3], "format", ex, new object[] { formatArg }); + Invoke(log, logMethods[4], CultureInfo.InvariantCulture, "format", new object[] {formatArg}); + Invoke(log, logMethods[5], CultureInfo.InvariantCulture, "format", ex, new object[] { formatArg }); + Invoke(log, logMethods[6], failCallback); + Invoke(log, logMethods[7], failCallback, ex); + Invoke(log, logMethods[8], CultureInfo.InvariantCulture, failCallback); + Invoke(log, logMethods[9], CultureInfo.InvariantCulture, failCallback, ex); + + mocks.VerifyAll(); + } +*/ + private static bool IsLevelEnabled(ILog log, string logLevelName) + { + switch(logLevelName) + { + case "Trace": + return log.IsTraceEnabled; + case "Debug": + return log.IsDebugEnabled; + case "Info": + return log.IsInfoEnabled; + case "Warn": + return log.IsWarnEnabled; + case "Error": + return log.IsErrorEnabled; + case "Fatal": + return log.IsFatalEnabled; + default: + throw new ArgumentOutOfRangeException("logLevelName", logLevelName, "unknown log level "); + } + } + + private static readonly Type[][] methodSignatures = + { + new Type[] {typeof (object)}, + new Type[] {typeof (object), typeof (Exception)}, + new Type[] {typeof (string), typeof (object[])}, + new Type[] {typeof (string), typeof (Exception), typeof (object[])}, + new Type[] {typeof (IFormatProvider), typeof (string), typeof (object[])}, + new Type[] {typeof (IFormatProvider), typeof (string), typeof (Exception), typeof (object[])}, + new Type[] {typeof (FormatMessageCallback)}, + new Type[] {typeof (FormatMessageCallback), typeof (Exception)}, + new Type[] {typeof (IFormatProvider), typeof (FormatMessageCallback)}, + new Type[] {typeof (IFormatProvider), typeof (FormatMessageCallback), typeof (Exception)} + }; + + private static MethodInfo[] GetLogMethodSignatures(string levelName) + { + return new MethodInfo[] + { + typeof (ILog).GetMethod(levelName, methodSignatures[0]), + typeof (ILog).GetMethod(levelName, methodSignatures[1]), + typeof (ILog).GetMethod(levelName + "Format", methodSignatures[2]), + typeof (ILog).GetMethod(levelName + "Format", methodSignatures[3]), + typeof (ILog).GetMethod(levelName + "Format", methodSignatures[4]), + typeof (ILog).GetMethod(levelName + "Format", methodSignatures[5]), + typeof (ILog).GetMethod(levelName, methodSignatures[6]), + typeof (ILog).GetMethod(levelName, methodSignatures[7]), + typeof (ILog).GetMethod(levelName, methodSignatures[8]), + typeof (ILog).GetMethod(levelName, methodSignatures[9]) + }; + } + + private static void Invoke(object target, MethodInfo method, params object[] args) + { + method.Invoke(target, args); + } + + #region TestFormatMessageCallback Utility Class + + private class TestFormatMessageCallback + { + private readonly bool throwOnInvocation; + private readonly string messageToReturn; + private readonly object[] argsToReturn; + + private TestFormatMessageCallback(bool throwOnInvocation) + { + this.throwOnInvocation = throwOnInvocation; + } + + private TestFormatMessageCallback(string messageToReturn, object[] args) + { + this.messageToReturn = messageToReturn; + this.argsToReturn = args; + } + + public static FormatMessageCallback FailCallback() + { + return new FormatMessageCallback(new TestFormatMessageCallback(true).FormatMessage); + } + + public static FormatMessageCallback MessageCallback(string message, params object[] args) + { + return new FormatMessageCallback(new TestFormatMessageCallback(message, args).FormatMessage); + } + + private void FormatMessage(FormatMessageHandler fmh) + { + if (throwOnInvocation) + { + Assert.Fail(); + } + fmh(messageToReturn, argsToReturn); + } + } + + #endregion + + private static string[] Exclude(string[] arr, params string[] exclude) + { + ArrayList result = new ArrayList(); + foreach (string s in arr) + { + if (0 > Array.BinarySearch(exclude, s)) + { + result.Add(s); + } + } + return (string[]) result.ToArray(typeof (string)); + } + + public class TestLogger : AbstractTestLogger + { + public LogLevel LastLogLevel; + public string LastMessage; + public Exception LastException; + + protected override WriteHandler GetWriteHandler() + { + return new WriteHandler(Log); + } + + protected override void WriteInternal(LogLevel level, object message, Exception exception) + { + Assert.Fail("must never been called - Log() should be called"); + } + + public override void Log(LogLevel level, object message, Exception exception) + { + LastLogLevel = level; + LastMessage = message.ToString(); + LastException = exception; + } + } + + public abstract class AbstractTestLogger : AbstractLogger + { + protected override void WriteInternal(LogLevel level, object message, Exception exception) + { + Log(level, message, exception); + } + + public abstract void Log(LogLevel level, object message, Exception exception); + + /// + /// Checks if this logger is enabled for the level. + /// + public override bool IsTraceEnabled + { + get { return true; } + } + + /// + /// Checks if this logger is enabled for the level. + /// + public override bool IsDebugEnabled + { + get { return true; } + } + + /// + /// Checks if this logger is enabled for the level. + /// + public override bool IsErrorEnabled + { + get { return true; } + } + + /// + /// Checks if this logger is enabled for the level. + /// + public override bool IsFatalEnabled + { + get { return true; } + } + + /// + /// Checks if this logger is enabled for the level. + /// + public override bool IsInfoEnabled + { + get { return true; } + } + + /// + /// Checks if this logger is enabled for the level. + /// + public override bool IsWarnEnabled + { + get { return true; } + } + } + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/LogManagerTests.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/LogManagerTests.cs new file mode 100644 index 0000000..9af4fe9 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/LogManagerTests.cs @@ -0,0 +1,63 @@ +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System; +using System.Diagnostics; +using Common.Logging.Configuration; +using Common.Logging.Simple; +using NUnit.Framework; +//using Rhino.Mocks; + +namespace Common.Logging +{ + /// + /// Tests for LogManager that exercise the basic API and check for error conditions. + /// + /// Mark Pollack + [TestFixture] + public class LogManagerTests + { + //public MockRepository mocks; + + [SetUp] + public void SetUp() + { + LogManager.Reset(); + //mocks = new MockRepository(); + } + + [Test] + public void AdapterProperty() + { + ILoggerFactoryAdapter adapter = new NoOpLoggerFactoryAdapter(); + LogManager.Adapter = adapter; + Assert.AreSame(adapter, LogManager.Adapter); + + Assert.Throws(delegate { LogManager.Adapter = null; }); + } + + [Test] + public void ConfigureFromSettings () + { + var logger = LogManager.GetCurrentClassLogger(); + logger.Info("Hi from plist config!"); + } + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/LoggingExceptionTests.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/LoggingExceptionTests.cs new file mode 100644 index 0000000..11fb8eb --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/LoggingExceptionTests.cs @@ -0,0 +1,42 @@ +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + + +using System.Reflection; +using NUnit.Framework; + +namespace Common.Logging +{ + /// + /// Test that exceptions declared in Common.Logging meet coding standards. + /// + /// Mark Pollack + /// $Id:$ + [TestFixture] + public class LoggingExceptionTests : ExceptionsTest + { + [TestFixtureSetUp] + public void FixtureSetUp() + { + AssemblyToCheck = Assembly.GetAssembly(typeof (ConfigurationException)); + } + + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/MissingCtorFactoryAdapter.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/MissingCtorFactoryAdapter.cs new file mode 100644 index 0000000..32132e9 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/MissingCtorFactoryAdapter.cs @@ -0,0 +1,49 @@ +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System; + +namespace Common.Logging +{ + /// + /// Class that does not have constructors used by LogManager to create the adapter. + /// + /// Mark Pollack + /// $Id:$ + public class MissingCtorFactoryAdapter : ILoggerFactoryAdapter + { + private string foo; + + public MissingCtorFactoryAdapter(string foo) + { + this.foo = foo; + } + + public ILog GetLogger(Type type) + { + throw new NotImplementedException(); + } + + public ILog GetLogger(string name) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/SImple/AbstractSimpleLoggerTests.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/SImple/AbstractSimpleLoggerTests.cs new file mode 100644 index 0000000..ddf2bdd --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/SImple/AbstractSimpleLoggerTests.cs @@ -0,0 +1,98 @@ +#region License + +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System; +using System.Collections.Specialized; +using NUnit.Framework; + +namespace Common.Logging.Simple +{ + /// + /// Tests the class. + /// + /// Erich Eichinger + [TestFixture] + public class AbstractSimpleLoggerTests + { + private class ConcreteLogger : AbstractSimpleLogger + { + public ConcreteLogger(string logName, LogLevel logLevel, bool showlevel, bool showDateTime, bool showLogName, string dateTimeFormat) : base(logName, logLevel, showlevel, showDateTime, showLogName, dateTimeFormat) + {} + + protected override void WriteInternal(LogLevel level, object message, Exception exception) + { + throw new NotImplementedException(); + } + } + + private class ConcreteLoggerFactory : AbstractSimpleLoggerFactoryAdapter + { + public ConcreteLoggerFactory(NameValueCollection properties) : base(properties) + { + } + + protected override ILog CreateLogger(string name, LogLevel level, bool showLevel, bool showDateTime, bool showLogName, string dateTimeFormat) + { + return new ConcreteLogger(name, level, showLevel, showDateTime, showLogName, dateTimeFormat); + } + } + + [Test] + public void IsSerializable() + { + Assert.IsTrue(SerializationTestUtils.IsSerializable()); + } + + [Test] + public void DefaultValues() + { + AbstractSimpleLogger logger; + logger = (AbstractSimpleLogger)new ConcreteLoggerFactory(null).GetLogger("x"); + Assert.AreEqual("x", logger.Name); + Assert.AreEqual(true, logger.ShowLogName); + Assert.AreEqual(true, logger.ShowDateTime); + Assert.AreEqual(true, logger.ShowLevel); + Assert.AreEqual(false, logger.HasDateTimeFormat); + Assert.AreEqual(string.Empty, logger.DateTimeFormat); + Assert.AreEqual(LogLevel.All, logger.CurrentLogLevel); + } + + [Test] + public void ConfiguredValues() + { + NameValueCollection props = new NameValueCollection(); + props["showLogName"] = "false"; + props["showLevel"] = "false"; + props["showDateTime"] = "false"; + props["dateTimeFormat"] = "MM"; + props["level"] = "Info"; + + AbstractSimpleLogger logger; + logger = (AbstractSimpleLogger)new ConcreteLoggerFactory(props).GetLogger("x"); + Assert.AreEqual("x", logger.Name); + Assert.AreEqual(false, logger.ShowLogName); + Assert.AreEqual(false, logger.ShowDateTime); + Assert.AreEqual(false, logger.ShowLevel); + Assert.AreEqual(true, logger.HasDateTimeFormat); + Assert.AreEqual("MM", logger.DateTimeFormat); + Assert.AreEqual(LogLevel.Info, logger.CurrentLogLevel); + } + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/SImple/AbstractSimpleLoggerTestsBase.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/SImple/AbstractSimpleLoggerTestsBase.cs new file mode 100644 index 0000000..c6f4e30 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/SImple/AbstractSimpleLoggerTestsBase.cs @@ -0,0 +1,46 @@ +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System.Collections.Specialized; + +namespace Common.Logging.Simple +{ + /// + /// Base class that exercises the basic api of the simple loggers. + /// To simplify testing derived classes you should derive your fixtures from this base fixture + /// + /// Mark Pollack + public abstract class AbstractSimpleLoggerTestsBase : ILogTestsBase + { + private static int count; + + protected static NameValueCollection CreateProperties() + { + NameValueCollection properties = new NameValueCollection(); + properties["showDateTime"] = "true"; + // if ((count % 2) == 0) + { + properties["dateTimeFormat"] = "yyyy/MM/dd HH:mm:ss:fff"; + } + count++; + return properties; + } + } +} diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/SImple/ConsoleOutLoggerTests.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/SImple/ConsoleOutLoggerTests.cs new file mode 100644 index 0000000..960e512 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Logging/SImple/ConsoleOutLoggerTests.cs @@ -0,0 +1,56 @@ +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using NUnit.Framework; + +namespace Common.Logging.Simple +{ + /// + /// Exercises the ConsoleOutLogger implementation. + /// + /// Mark Pollack + [TestFixture] + public class ConsoleOutLoggerTests : AbstractSimpleLoggerTestsBase + { + protected override ILoggerFactoryAdapter GetLoggerFactoryAdapter() + { + return new ConsoleOutLoggerFactoryAdapter(CreateProperties()); + } + + /// + /// Basic checks specific to ConsoleOutLogger + /// + [Test] + public void AssertDefaultSettings() + { + ILog log = LogManager.GetCurrentClassLogger(); + + Assert.IsNotNull(log); + Assert.AreEqual(typeof(ConsoleOutLogger),log.GetType()); + + // Can we call level checkers with no exceptions? + Assert.IsTrue(log.IsDebugEnabled); + Assert.IsTrue(log.IsInfoEnabled); + Assert.IsTrue(log.IsWarnEnabled); + Assert.IsTrue(log.IsErrorEnabled); + Assert.IsTrue(log.IsFatalEnabled); + } + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Main.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Main.cs new file mode 100644 index 0000000..d8e37cf --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Main.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using MonoTouch.Foundation; +using MonoTouch.UIKit; + +namespace Common.Logging.MonoTouch.Tests +{ + public class Application + { + // This is the main entry point of the application. + static void Main (string[] args) + { + // if you want to use a different Application Delegate class from "UnitTestAppDelegate" + // you can specify it here. + UIApplication.Main (args, null, "UnitTestAppDelegate"); + } + } +} diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/MethodInvokePerformanceTests.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/MethodInvokePerformanceTests.cs new file mode 100644 index 0000000..5e9c06d --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/MethodInvokePerformanceTests.cs @@ -0,0 +1,62 @@ +using System; +using NUnit.Framework; + +namespace Common +{ + internal interface IWriteHandler + { + void PerformanceTestTarget(int z, object message, Exception ex); + } + + [TestFixture, Explicit] + public class MethodInvokePerformanceTests : IWriteHandler + { + private delegate void WriteHandler(int x, object message, Exception ex); + + [Test] + public void DelegatePerformanceTest() + { + int runs = 5000000; + + StopWatch sw; + sw = new StopWatch(); + using(sw.Start("Time:{0}")) + { + for (int i = 0; i < runs; i++) + { + PerformanceTestTarget(1, null, null); + } + } +// Trace.WriteLine( string.Format("Time:{0}", sw.Elapsed.TotalSeconds) ); + + WriteHandler writeHandler = new WriteHandler(PerformanceTestTarget); + using(sw.Start("Time:{0}")) + { + for (int i = 0; i < runs; i++) + { + writeHandler(1, null, null); + } + } +// Trace.WriteLine(string.Format("Time:{0}", sw.Elapsed.TotalSeconds)); + + IWriteHandler writeHandler2 = this; + using(sw.Start("Time:{0}")) + { + for (int i = 0; i < runs; i++) + { + writeHandler2.PerformanceTestTarget(1, null, null); + } + } +// Trace.WriteLine(string.Format("Time:{0}", sw.Elapsed.TotalSeconds)); + } + + public void PerformanceTestTarget(int z, object message, Exception ex) + { + double x = 2.1; + for(int i=0;i<10;i++) + { + x = x * x * x; + } + } + } +} diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Settings.bundle/Common.Logging b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Settings.bundle/Common.Logging new file mode 100644 index 0000000..6631ffa --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Settings.bundle/Common.Logging @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Settings.bundle/Common.Logging.plist b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Settings.bundle/Common.Logging.plist new file mode 100644 index 0000000..29f6bd0 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Settings.bundle/Common.Logging.plist @@ -0,0 +1,18 @@ + + + + + dateTimeFormat + yyyy-MM-dd HH:MI:SS + logLevel + Debug + logName + log4net for monotouch tests + showDateTime + true + showLevel + true + showLogName + true + + diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Settings.bundle/Root.plist b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Settings.bundle/Root.plist new file mode 100644 index 0000000..943b963 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/Settings.bundle/Root.plist @@ -0,0 +1,62 @@ + + + + + PreferenceSpecifiers + + + Type + PSGroupSpecifier + Title + Group + + + Type + PSTextFieldSpecifier + Title + Name + KeyboardType + Alphabet + AutocapitalizationType + None + AutocorrectionType + No + IsSecure + + Key + name_preference + DefaultValue + + + + Type + PSToggleSwitchSpecifier + Title + Enabled + Key + enabled_preference + DefaultValue + + + + Type + PSSliderSpecifier + MaximumValue + 1 + MaximumValueImage + + MinimumValue + 0 + MinimumValueImage + + Key + slider_preference + DefaultValue + 0.5 + + + StringsTable + Root + + + diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/StandardsComplianceTest.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/StandardsComplianceTest.cs new file mode 100644 index 0000000..2b832e0 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/StandardsComplianceTest.cs @@ -0,0 +1,109 @@ +#region License + +/* + * Copyright 2004-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Common +{ + /// + /// Base class for tests that check standards compliance. + /// + /// Rick Evans + public abstract class StandardsComplianceTest + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the class. + /// + /// + /// + /// This is an class, and as such has no publicly visible + /// constructors. + /// + /// + protected StandardsComplianceTest() + { + } + + #endregion + + #region Properties + + protected Type CheckedType + { + get { return checkedType; } + set { checkedType = value; } + } + + #endregion + + #region Methods + + private bool IsCheckedType(Type type) + { + if (CheckedType.IsInterface) + { + Type iface = type.GetInterface(CheckedType.Name, false); + return iface != null; + } + else + { + Type baseType = null; + while ((baseType = type.BaseType) != null) + { + if (baseType == CheckedType) + { + return true; + } + type = baseType; + } + } + return false; + } + + protected void ProcessAssembly(Assembly a) + { + foreach (Type t in a.GetTypes()) + { + if (IsCheckedType(t)) + { + CheckStandardsCompliance(a, t); + } + } + } + + protected abstract void CheckStandardsCompliance( + Assembly assembly, Type t); + + #endregion + + #region Fields + + private Type checkedType; + + #endregion + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/StopWatch.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/StopWatch.cs new file mode 100644 index 0000000..ab09bd0 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/StopWatch.cs @@ -0,0 +1,99 @@ +#region License + +/* + * Copyright © 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Common +{ + /// + /// A simple StopWatch implemetion for use in Performance Tests + /// + /// + /// The following example shows the usage: + /// + /// StopWatch watch = new StopWatch(); + /// using (watch.Start("Duration: {0}")) + /// { + /// // do some work... + /// } + /// + /// The format string passed to the start method is used to print the result message. + /// The example above will print Duration: 0.123s. + /// + /// Erich Eichinger + public class StopWatch + { + private DateTime _startTime; + private TimeSpan _elapsed; + + private class Stopper : IDisposable + { + private readonly StopWatch _owner; + private readonly string _format; + + public Stopper(StopWatch owner, string format) + { + _owner = owner; + _format = format; + } + + public void Dispose() + { + _owner.Stop(_format); + GC.SuppressFinalize(this); + } + } + + /// + /// Starts the timer and returns and "handle" that must be disposed to stop the timer. + /// + /// the output format string, that is used to render the result message + /// the handle to dispose for stopping the timer + public IDisposable Start(string outputFormat) + { + Stopper stopper = new Stopper(this, outputFormat); + _startTime = DateTime.Now; + return stopper; + } + + private void Stop(string outputFormat) + { + _elapsed = DateTime.Now.Subtract(_startTime); + if (outputFormat != null) + { + Console.WriteLine(outputFormat, _elapsed); + } + } + + public DateTime StartTime + { + get { return _startTime; } + } + + public TimeSpan Elapsed + { + get { return _elapsed; } + } + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/UnitTestAppDelegate.cs b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/UnitTestAppDelegate.cs new file mode 100644 index 0000000..4dc25a7 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.Tests/UnitTestAppDelegate.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using MonoTouch.Foundation; +using MonoTouch.UIKit; +using MonoTouch.NUnit.UI; + +namespace Common.Logging.MonoTouch.Tests +{ + // The UIApplicationDelegate for the application. This class is responsible for launching the + // User Interface of the application, as well as listening (and optionally responding) to + // application events from iOS. + [Register ("UnitTestAppDelegate")] + public partial class UnitTestAppDelegate : UIApplicationDelegate + { + // class-level declarations + UIWindow window; + TouchRunner runner; + + // + // This method is invoked when the application has loaded and is ready to run. In this + // method you should instantiate the window, load the UI into it and then make the window + // visible. + // + // You have 17 seconds to return from this method, or iOS will terminate your application. + // + public override bool FinishedLaunching (UIApplication app, NSDictionary options) + { + // create a new window instance based on the screen size + window = new UIWindow (UIScreen.MainScreen.Bounds); + runner = new TouchRunner (window); + + // register every tests included in the main application/assembly + runner.Add (System.Reflection.Assembly.GetExecutingAssembly ()); + + window.RootViewController = new UINavigationController (runner.GetViewController ()); + + // make the window visible + window.MakeKeyAndVisible (); + + return true; + } + } +} + diff --git a/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.csproj b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.csproj new file mode 100644 index 0000000..7e42c45 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.MonoTouch.csproj @@ -0,0 +1,135 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {C5FED159-541C-4245-95CA-661C4E29A2DD} + {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + Common.Logging.MonoTouch + Resources + Common.Logging.MonoTouch + + + true + full + false + bin\Debug + DEBUG;MONOTOUCH; + prompt + 4 + false + + + full + true + bin\Release + prompt + 4 + false + + + + + + + + + + + + + + + AssemblyDoc.cs + + + AssemblyInfo.cs + + + CoverageExcludeAttribute.cs + + + NamespaceDoc_Introduction.cs + + + Logging\ConfigurationException.cs + + + Logging\FormatMessageHandler.cs + + + Logging\IConfigurationReader.cs + + + Logging\ILog.cs + + + Logging\ILoggerFactoryAdapter.cs + + + Logging\LogLevel.cs + + + Logging\LogManager.cs + + + Logging\NamespaceDoc.cs + + + Logging\Configuration\ArgUtils.cs + + + Logging\Configuration\LogSetting.cs + + + Logging\Configuration\NamespaceDoc.cs + + + Logging\Factory\AbstractCachingLoggerFactoryAdapter.cs + + + Logging\Factory\AbstractLogger.cs + + + Logging\Factory\NamespaceDoc.cs + + + Logging\Simple\AbstractSimpleLogger.cs + + + Logging\Simple\AbstractSimpleLoggerFactoryAdapter.cs + + + Logging\Simple\CapturingLogger.cs + + + Logging\Simple\CapturingLoggerEvent.cs + + + Logging\Simple\CapturingLoggerFactoryAdapter.cs + + + Logging\Simple\ConsoleOutLogger.cs + + + Logging\Simple\ConsoleOutLoggerFactoryAdapter.cs + + + Logging\Simple\ExceptionFormatter.cs + + + Logging\Simple\NamespaceDoc.cs + + + Logging\Simple\NoOpLogger.cs + + + Logging\Simple\NoOpLoggerFactoryAdapter.cs + + + + + \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/Common.Logging.TestUtils.MonoTouch.csproj b/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/Common.Logging.TestUtils.MonoTouch.csproj new file mode 100644 index 0000000..f9b9867 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/Common.Logging.TestUtils.MonoTouch.csproj @@ -0,0 +1,55 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {B928FD65-4E80-4F9D-96D0-830EDB3092DB} + {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + Common.Logging.TestUtlis.MonoTouch + Resources + Common.Logging.TestUtlis.MonoTouch + + + True + full + False + bin\Debug + DEBUG; + prompt + 4 + False + + + none + True + bin\Release + prompt + 4 + False + + + + + + + + + + + + + + + + + + + + {C5FED159-541C-4245-95CA-661C4E29A2DD} + Common.Logging.MonoTouch + + + \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/Logging/ILogTestsBase.cs b/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/Logging/ILogTestsBase.cs new file mode 100644 index 0000000..ac155e1 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/Logging/ILogTestsBase.cs @@ -0,0 +1,158 @@ +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System; +using System.Diagnostics; +using System.Reflection; +using System.Security; +using System.Security.Permissions; +using NUnit.Framework; +using Common.TestUtil; + +namespace Common.Logging +{ + /// + /// Generic tests that can be applied to any log implementation by + /// subclassing and defining the property LogObject. + /// + /// + /// Exercises basic API of the ILog implemetation. + /// + /// Mark Pollack + // [TestFixture] + public abstract class ILogTestsBase + { + [SetUp] + public virtual void SetUp() + { + //Security = new SecurityTemplate(true); + LogManager.Reset(); + LogManager.Adapter = GetLoggerFactoryAdapter(); + } + + protected abstract ILoggerFactoryAdapter GetLoggerFactoryAdapter(); + + [Test] + public void LoggingWithNullParameters() + { + Console.Out.WriteLine("Executing Test " + MethodBase.GetCurrentMethod().Name); + ILog log = LogManager.GetCurrentClassLogger(); + + log.Trace((object)null); + log.Trace((object)null, null); + log.Trace((Action)null); + log.Trace((Action)null, null); + log.Trace(null, (Action)null); + log.Trace(null, (Action)null, null); + log.TraceFormat((string)null); + log.TraceFormat(null, (Exception)null); + log.TraceFormat((IFormatProvider)null, null); + log.TraceFormat((IFormatProvider)null, null, (Exception)null); + + log.Debug((object)null); + log.Debug((object)null, null); + log.Debug((Action)null); + log.Debug((Action)null, null); + log.Debug(null, (Action)null); + log.Debug(null, (Action)null, null); + log.Debug(null); + log.Debug(null, (Exception)null); + log.Debug((IFormatProvider)null, null); + log.Debug((IFormatProvider)null, null, (Exception)null); + + } + + [Test] + public void CanCallIsEnabledFromNamedLog() + { + CanCallIsEnabled(LogManager.GetLogger("loggerName")); + } + + [Test] + public void CanLogMessageFromNamedLog() + { + CanLogMessage(LogManager.GetLogger("logger2Name")); + } + + [Test] + public void CanLogMessageWithExceptionFromNamedLog() + { + ILog log = LogManager.GetLogger("logger3Name"); + CanLogMessageWithException(log); + } + + [Test] + public void CanLogMessageWithExceptionFromTypeLog() + { + ILog log = LogManager.GetCurrentClassLogger(); + CanLogMessageWithException(log); + } + + protected virtual void CanCallIsEnabled(ILog log) + { + bool b; + b = log.IsTraceEnabled; + b = log.IsDebugEnabled; + b = log.IsInfoEnabled; + b = log.IsWarnEnabled; + b = log.IsErrorEnabled; + b = log.IsFatalEnabled; + } + + protected virtual void CanLogMessage(ILog log) + { + log.Trace("Hi Trace"); + log.Debug("Hi Debug"); + log.Info("Hi Info"); + log.Warn("Hi Warn"); + log.Error("Hi Error"); + log.Fatal("Hi Fatal"); + } + +#if NET_3_0 + protected virtual void CanLogMessageWithException(ILog log) + { + log.Trace(m => m("Hi {0}", "dude")); + log.Debug(m => m("Hi {0}", "dude"), new ArithmeticException()); + log.Info(m => m("Hi {0}", "dude"), new ArithmeticException()); + log.Warn(m => m("Hi {0}", "dude"), new ArithmeticException()); + log.Error(m => m("Hi {0}", "dude"), new ArithmeticException()); + log.Fatal(m => m("Hi {0}", "dude"), new ArithmeticException()); + } +#else + protected virtual void CanLogMessageWithException(ILog log) + { + log.TraceFormat("Hi {0}", new ArithmeticException(), "Trace"); + log.DebugFormat("Hi {0}", new ArithmeticException(), "Debug"); + log.InfoFormat("Hi {0}", new ArithmeticException(), "Info"); + log.WarnFormat("Hi {0}", new ArithmeticException(), "Warn"); + log.ErrorFormat("Hi {0}", new ArithmeticException(), "Error"); + log.FatalFormat("Hi {0}", new ArithmeticException(), "Fatal"); + } +#endif + + protected delegate TResult Func(TArg1 arg1); + + protected MethodBase GetMember(Func action) + { + return action.Method; + } + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/Properties/AssemblyInfo.cs b/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3e71e62 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +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("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[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("1ae77e17-60c0-473f-be37-657900f0f8e2")] + +// 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("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/TestUtil/SerializationTestUtils.cs b/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/TestUtil/SerializationTestUtils.cs new file mode 100644 index 0000000..7b645bb --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/TestUtil/SerializationTestUtils.cs @@ -0,0 +1,135 @@ +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System; +using System.IO; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using NUnit.Framework; + +namespace Common.Logging +{ + /// + /// Utilities for testing serializability of objects. + /// + /// + /// Exposes static methods for use in other test cases. + /// + /// Erich Eichinger + [TestFixture] + public sealed class SerializationTestUtils + { + #region Test Ourselves + + [Test] + [ExpectedException(typeof(SerializationException))] + public void WithNonSerializableObject() + { + TestObject o = new TestObject(); + Assert.IsFalse(o is ISerializable); + Assert.IsFalse(IsSerializable(o)); + TrySerialization(o); + } + + [Test] + public void WithSerializableObject() + { + SerializableTestObject pA = new SerializableTestObject("propA"); + Assert.IsTrue(IsSerializable(pA)); + TrySerialization(pA); + SerializableTestObject pB = SerializeAndDeserialize(pA); + Assert.IsFalse(ReferenceEquals(pA, pB)); + Assert.AreEqual(pA.SomeProperty, pB.SomeProperty); + } + + #endregion + + /// + /// Attempts to serialize the specified object to an in-memory stream. + /// + /// the object to serialize + public static void TrySerialization(object o) + { + using (Stream stream = new MemoryStream()) + { + BinaryFormatter bformatter = new BinaryFormatter(); + bformatter.Serialize(stream, o); + } + } + + /// + /// Tests whether the specified object is serializable. + /// + /// the object to test. + /// true if the object is serializable, otherwise false. + public static bool IsSerializable(object o) + { + return o == null ? true : o.GetType().IsSerializable; + } + + /// + /// Tests whether instances of the specified type are serializable. + /// + /// true if the type is serializable, otherwise false. + public static bool IsSerializable() + { + return typeof(T).IsSerializable; + } + + /// + /// Serializes the specified object to an in-memory stream, and returns + /// the result of deserializing the object stream. + /// + /// the object to use. + /// the deserialized object. + public static T SerializeAndDeserialize(T o) + { + using (Stream stream = new MemoryStream()) + { + BinaryFormatter bformatter = new BinaryFormatter(); + bformatter.Serialize(stream, o); + stream.Flush(); + + stream.Seek(0, SeekOrigin.Begin); + T o2 = (T)bformatter.Deserialize(stream); + return o2; + } + } + + #region Test Classes + + private class TestObject + { + } + + [Serializable] + private class SerializableTestObject + { + public readonly string SomeProperty; + + public SerializableTestObject(string someProperty) + { + SomeProperty = someProperty; + } + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/TestUtil/TraceEventArgs.cs b/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/TestUtil/TraceEventArgs.cs new file mode 100644 index 0000000..a6ca827 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Common.Logging.TestUtils.MonoTouch/TestUtil/TraceEventArgs.cs @@ -0,0 +1,54 @@ +using System; +using System.Diagnostics; +using System.Text; + +namespace Common.TestUtil +{ + public class TraceEventArgs + { + public string Source; + public string Category; + public int? Id; + public object[] Data; + public object Format; + public object[] Args; + public Guid? RelatedActivityId; + + public TraceEventArgs(string source, string category, int? id, object message, object[] args, object[] data, Guid? relatedActivityId) + { + Source = source; + Category = category; + Id = id; + Format = message; + Args = args; + Data = data; + RelatedActivityId = relatedActivityId; + } + + public string FormattedMessage + { + get + { + string msg = null; + if (Format == null && Data != null) + { + StringBuilder sb = new StringBuilder(); + foreach(object d in Data) + { + sb.Append(d); + } + msg = sb.ToString(); + } + else + { + msg = "" + Format; + } + if (Args != null) + { + return string.Format(msg, Args); + } + return msg; + } + } + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Logging/Configuration/DefaultConfigurationReader.cs b/src/Common.Logging.MonoTouch/Logging/Configuration/DefaultConfigurationReader.cs new file mode 100644 index 0000000..02a6881 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Logging/Configuration/DefaultConfigurationReader.cs @@ -0,0 +1,57 @@ +#region License + +/* + * Copyright © 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion +using MonoTouch.Foundation; +using Common.Logging.Simple; +using System.Collections.Specialized; + +namespace Common.Logging.Configuration +{ + /// + /// MonoTouch implementation of configuration reader. Each section corresponds to a plist on the device. + /// + /// adamnation + public class DefaultConfigurationReader : IConfigurationReader + { + /// + /// Parses the configuration section and returns the resulting object. + /// + /// Path to the plist on the device + /// + /// NSDictionary of the settings in the plist. + /// + /// + /// + /// Primary purpose of this method is to allow us to load settings from a plist on the device. + /// + /// + /// + public object GetSection (string sectionName) + { + NameValueCollection properties = new NameValueCollection(); + var nsDict = new NSDictionary (NSBundle.MainBundle.PathForResource (sectionName, null)); + foreach (var key in nsDict.Keys) + { + properties.Add(key.ToString(), nsDict[key].ToString()); + } + + return new ConsoleOutLoggerFactoryAdapter(properties); + } + } +} \ No newline at end of file diff --git a/src/Common.Logging.MonoTouch/Logging/MonoNet/CollectionsUtil.cs b/src/Common.Logging.MonoTouch/Logging/MonoNet/CollectionsUtil.cs new file mode 100644 index 0000000..c570861 --- /dev/null +++ b/src/Common.Logging.MonoTouch/Logging/MonoNet/CollectionsUtil.cs @@ -0,0 +1,64 @@ +// +// System.Collections.Specialized.CollectionsUtil.cs +// +// Author: +// Lawrence Pit (loz@cable.a2000.nl) +// + +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Collections; + +namespace System.Collections.Specialized { + +#if !NET_2_1 + public +#else + internal +#endif + class CollectionsUtil { + + public CollectionsUtil () {} + + public static Hashtable CreateCaseInsensitiveHashtable () + { + return new Hashtable (CaseInsensitiveHashCodeProvider.Default, + CaseInsensitiveComparer.Default); + } + + + public static Hashtable CreateCaseInsensitiveHashtable (IDictionary d) { + return new Hashtable (d, CaseInsensitiveHashCodeProvider.Default, + CaseInsensitiveComparer.Default); + } + + public static Hashtable CreateCaseInsensitiveHashtable (int capacity) { + return new Hashtable (capacity, CaseInsensitiveHashCodeProvider.Default, + CaseInsensitiveComparer.Default); + } + + + public static SortedList CreateCaseInsensitiveSortedList () { + return new SortedList (CaseInsensitiveComparer.Default); + } + } +} \ No newline at end of file diff --git a/src/Common.Logging/Common.Logging.2010-net40.csproj b/src/Common.Logging/Common.Logging.2010-net40.csproj index 6b04a6c..99cb7cf 100644 --- a/src/Common.Logging/Common.Logging.2010-net40.csproj +++ b/src/Common.Logging/Common.Logging.2010-net40.csproj @@ -94,6 +94,7 @@ Code + diff --git a/src/Common.Logging/Common.Logging.2010.csproj b/src/Common.Logging/Common.Logging.2010.csproj index 682d0b3..50affa4 100644 --- a/src/Common.Logging/Common.Logging.2010.csproj +++ b/src/Common.Logging/Common.Logging.2010.csproj @@ -92,6 +92,7 @@ Code + diff --git a/src/Common.Logging/Logging/Configuration/ArgUtils.cs b/src/Common.Logging/Logging/Configuration/ArgUtils.cs index fa1cc73..b14b75e 100644 --- a/src/Common.Logging/Logging/Configuration/ArgUtils.cs +++ b/src/Common.Logging/Logging/Configuration/ArgUtils.cs @@ -146,25 +146,25 @@ public static T Coalesce(Predicate predicate, params T[] values) where T : /// the successfully parsed value, otherwise. public static T TryParseEnum(T defaultValue, string stringValue) where T : struct { - if (!typeof(T).IsEnum) + Type enumType = typeof(T); + if (!enumType.IsEnum) { throw new ArgumentException(string.Format("Type '{0}' is not an enum type", typeof(T).FullName)); } - - T result = defaultValue; - if (string.IsNullOrEmpty(stringValue)) - { - return defaultValue; - } + try { - result = (T)Enum.Parse(typeof(T), stringValue, true); + // If a string is specified then try to parse and return it + if (!string.IsNullOrEmpty(stringValue)) + { + return (T)Enum.Parse(enumType, stringValue, true); + } } catch { Trace.WriteLine(string.Format("WARN: failed converting value '{0}' to enum type '{1}'", stringValue, defaultValue.GetType().FullName)); } - return result; + return defaultValue; } /// diff --git a/src/Common.Logging/Logging/IConfigurationReader.cs b/src/Common.Logging/Logging/IConfigurationReader.cs index 2822a08..52dd1c1 100644 --- a/src/Common.Logging/Logging/IConfigurationReader.cs +++ b/src/Common.Logging/Logging/IConfigurationReader.cs @@ -18,8 +18,6 @@ #endregion -using System.Configuration; - namespace Common.Logging { diff --git a/src/Common.Logging/Logging/LogManager.cs b/src/Common.Logging/Logging/LogManager.cs index 2f3b306..317cc29 100644 --- a/src/Common.Logging/Logging/LogManager.cs +++ b/src/Common.Logging/Logging/LogManager.cs @@ -83,8 +83,11 @@ public static class LogManager /// You can always change the source of your configuration settings by setting another instance /// on . /// +#if MONOTOUCH + public static readonly string COMMON_LOGGING_SECTION = "Settings.bundle/Common.Logging.plist"; +#else public static readonly string COMMON_LOGGING_SECTION = "common/logging"; - +#endif private static IConfigurationReader _configurationReader; private static ILoggerFactoryAdapter _adapter; private static readonly object _loadLock = new object(); diff --git a/src/Common.Logging/Logging/Simple/AbstractSimpleLogger.cs b/src/Common.Logging/Logging/Simple/AbstractSimpleLogger.cs index fb541ed..d9195a8 100644 --- a/src/Common.Logging/Logging/Simple/AbstractSimpleLogger.cs +++ b/src/Common.Logging/Logging/Simple/AbstractSimpleLogger.cs @@ -177,7 +177,7 @@ protected virtual void FormatOutput(StringBuilder stringBuilder, LogLevel level, // Append stack trace if not null if (e != null) { - stringBuilder.Append(Environment.NewLine).Append(e.ToString()); + stringBuilder.Append(Environment.NewLine).Append(ExceptionFormatter.Format(e)); } } diff --git a/src/Common.Logging/Logging/Simple/ExceptionFormatter.cs b/src/Common.Logging/Logging/Simple/ExceptionFormatter.cs new file mode 100644 index 0000000..6a130cc --- /dev/null +++ b/src/Common.Logging/Logging/Simple/ExceptionFormatter.cs @@ -0,0 +1,252 @@ +#region License + +/* + * Copyright © 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System; +using System.Collections; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Globalization; + +namespace Common.Logging.Simple +{ + /// + /// + internal static class ExceptionFormatter + { + // constants + private const String STANDARD_DELIMETER = + "================================================================================\r\n"; + private const String INNERMOST_DELIMETER = + "=======================================================(inner most exception)===\r\n"; + + internal static String Format(Exception exception) + { + return Format(exception, CultureInfo.InvariantCulture); + } + + internal static String Format(Exception exception, IFormatProvider formatProvider) + { + if (exception == null) + return null; + + // push all inner exceptions onto stack + var exceptionStack = new Stack(); + var currentException = exception; + while (currentException != null) + { + exceptionStack.Push(currentException); + currentException = currentException.InnerException; + } + + // go through inner exceptions in reverse order + var sb = new StringBuilder(); + for (Int32 i = 1; exceptionStack.Count > 0; i++) + { + currentException = (Exception)exceptionStack.Pop(); + FormatSingleException(formatProvider, sb, currentException, i); + } + + // that's it; return result + return sb.ToString(); + } + + private static void FormatSingleException(IFormatProvider formatProvider, StringBuilder sb, Exception exception, + Int32 exceptionIndex) + { + OutputHeader(formatProvider, sb, exception, exceptionIndex); + OutputDetails(formatProvider, sb, exception); + OutputMessage(formatProvider, sb, exception); + OutputProperties(formatProvider, sb, exception); + OutputData(formatProvider, sb, exception); + OutputStackTrace(formatProvider, sb, exception); + sb.Append(STANDARD_DELIMETER); + } + + private static void OutputHeader(IFormatProvider formatProvider, StringBuilder sb, Exception exception, + Int32 exceptionIndex) + { + // output header: + // + // =======================================================(inner most exception)=== + // (index) exception-type-name + // ================================================================================ + // + sb.Append(exceptionIndex == 1 ? INNERMOST_DELIMETER : STANDARD_DELIMETER); + sb.AppendFormat(formatProvider, " ({0}) {1}\r\n", + exceptionIndex, exception.GetType().FullName); + sb.Append(STANDARD_DELIMETER); + } + + private static void OutputDetails(IFormatProvider formatProvider, StringBuilder sb, Exception exception) + { + // output exception details: + // + // Method : set_Attributes + // Type : System.IO.FileSystemInfo + // Assembly : mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + // Assembly Path : C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll + // Source : mscorlib + // Thread : 123 'TestRunnerThread' + // Helplink : + // + String assemblyName, assemblyModuleName, typeName, methodName; + String source, helplink; + + SafeGetTargetSiteInfo(exception, out assemblyName, out assemblyModuleName, out typeName, out methodName); + SafeGetSourceAndHelplink(exception, out source, out helplink); + + sb.AppendFormat(formatProvider, + "Method : {0}\r\n" + + "Type : {1}\r\n" + + "Assembly : {2}\r\n" + + "Assembly Path : {3}\r\n" + + "Source : {4}\r\n" + + "Thread : {5} '{6}'\r\n" + + "Helplink : {7}\r\n", + methodName, typeName, assemblyName, assemblyModuleName, + source, + Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.Name, + helplink); + } + + private static void OutputMessage(IFormatProvider formatProvider, StringBuilder sb, Exception exception) + { + // output exception message: + // + // Message: + // "..." + // + sb.AppendFormat(formatProvider, "\r\nMessage:\r\n\"{0}\"\r\n", + exception.Message); + } + + private static void OutputProperties(IFormatProvider formatProvider, StringBuilder sb, Exception exception) + { + // output exception properties: + // + // Properties: + // ArgumentException.ParamName = "text" + // + var properties = exception.GetType().GetProperties(BindingFlags.FlattenHierarchy | + BindingFlags.Instance | BindingFlags.Public); + + Boolean first = true; + foreach (PropertyInfo property in properties) + { + if (property.DeclaringType == typeof(Exception)) + continue; + if (property.Name == "Message") + continue; + + if (first) + { + first = false; + sb.Append("\r\nProperties:\r\n"); + } + + Object propertyValue = ""; + if (property.CanRead) + propertyValue = property.GetValue(exception, null); + + var enumerableValue = propertyValue as IEnumerable; + + if (enumerableValue == null || propertyValue is String) + { + sb.AppendFormat(formatProvider, " {0}.{1} = \"{2}\"\r\n", + property.ReflectedType.Name, property.Name, propertyValue); + } + else + { + sb.AppendFormat(formatProvider, " {0}.{1} = {{\r\n", + property.ReflectedType.Name, property.Name); + + foreach (var item in enumerableValue) + sb.AppendFormat(" \"{0}\",\r\n", item != null ? item.ToString() : ""); + + sb.Append(" }\r\n"); + } + } + } + + private static void OutputData(IFormatProvider formatProvider, StringBuilder sb, Exception exception) + { + // output exception properties: + // + // Data: + // Name = "value" + // + if (exception.Data.Count > 0) + { + sb.Append("\r\nData:\r\n"); + foreach (DictionaryEntry entry in exception.Data) + { + sb.AppendFormat(formatProvider, + "{0} = \"{1}\"\r\n", + entry.Key, entry.Value); + } + } + } + + private static void OutputStackTrace(IFormatProvider formatProvider, StringBuilder sb, Exception exception) + { + // output stack trace: + // + // Stack Trace: + // at System.IO.FileSystemInfo.set_Attributes(FileAttributes value) + // at Common.Logging.LogStoreWriter._SetupRootFolder() + // at Common.Logging.LogStoreWriter..ctor(String rootPath, Int32 maxStoreSize, Int32 minBacklogs) + // + sb.AppendFormat(formatProvider, "\r\nStack Trace:\r\n{0}\r\n", + exception.StackTrace); + } + + private static void SafeGetTargetSiteInfo(Exception exception, out String assemblyName, out String assemblyModulePath, + out String typeName, out String methodName) + { + assemblyName = ""; + assemblyModulePath = ""; + typeName = ""; + methodName = ""; + + MethodBase targetSite = exception.TargetSite; + + if (targetSite != null) + { + methodName = targetSite.Name; + Type type = targetSite.ReflectedType; + + typeName = type.FullName; + Assembly assembly = type.Assembly; + + assemblyName = assembly.FullName; + Module assemblyModule = assembly.ManifestModule; + + assemblyModulePath = assemblyModule.FullyQualifiedName; + } + } + + private static void SafeGetSourceAndHelplink(Exception exception, out String source, out String helplink) + { + source = exception.Source; + helplink = exception.HelpLink; + } + } +} \ No newline at end of file diff --git a/src/CommonAssemblyInfo.cs b/src/CommonAssemblyInfo.cs index 2e686b2..6502561 100644 --- a/src/CommonAssemblyInfo.cs +++ b/src/CommonAssemblyInfo.cs @@ -22,7 +22,7 @@ [assembly: AssemblyTrademarkAttribute("Apache License, Version 2.0")] [assembly: AssemblyCultureAttribute("")] [assembly: AssemblyVersionAttribute("2.1.2")] -[assembly: AssemblyConfigurationAttribute("net-4.0.win32; release")] -[assembly: AssemblyInformationalVersionAttribute("2.1.2; net-4.0.win32; release")] +[assembly: AssemblyConfigurationAttribute("monotouch; release")] +[assembly: AssemblyInformationalVersionAttribute("2.1.2; monotouch; release")] [assembly: AssemblyDelaySignAttribute(false)]
+ /// StopWatch watch = new StopWatch(); + /// using (watch.Start("Duration: {0}")) + /// { + /// // do some work... + /// } + ///
+ /// Primary purpose of this method is to allow us to load settings from a plist on the device. + ///