diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/ClosedXML_Tests.csproj b/ClosedXML/ClosedXML/ClosedXML_Tests/ClosedXML_Tests.csproj
index d41cb2d..eefeed8 100644
--- a/ClosedXML/ClosedXML/ClosedXML_Tests/ClosedXML_Tests.csproj
+++ b/ClosedXML/ClosedXML/ClosedXML_Tests/ClosedXML_Tests.csproj
@@ -62,7 +62,8 @@
-
+
+
@@ -70,7 +71,9 @@
-
+
+
+
diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/ExcelDocsComparer.cs b/ClosedXML/ClosedXML/ClosedXML_Tests/ExcelDocsComparer.cs
deleted file mode 100644
index 50a6c77..0000000
--- a/ClosedXML/ClosedXML/ClosedXML_Tests/ExcelDocsComparer.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.IO;
-
-namespace ClosedXML_Tests
-{
- internal static class ExcelDocsComparer
- {
- public static bool Compare(Stream filePathOne, Stream filePathOther, out string message)
- {
- message = null;
- return true;
- }
- }
-}
\ No newline at end of file
diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/ExcelDocsComparerTests.cs b/ClosedXML/ClosedXML/ClosedXML_Tests/ExcelDocsComparerTests.cs
new file mode 100644
index 0000000..adc2a92
--- /dev/null
+++ b/ClosedXML/ClosedXML/ClosedXML_Tests/ExcelDocsComparerTests.cs
@@ -0,0 +1,61 @@
+using System.IO;
+using ClosedXML_Examples;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace ClosedXML_Tests
+{
+ [TestClass]
+ public class ExcelDocsComparerTests
+ {
+ [TestMethod]
+ public void CheckEqual()
+ {
+ string left = ExampleHelper.GetTempFilePath();
+ string right = ExampleHelper.GetTempFilePath();
+ try
+ {
+ new BasicTable().Create(left);
+ new BasicTable().Create(right);
+ string message;
+ Assert.IsTrue(ExcelDocsComparer.Compare(left, right, out message));
+ }
+ finally
+ {
+ if (File.Exists(left))
+ {
+ File.Delete(left);
+ }
+ if (File.Exists(right))
+ {
+ File.Delete(right);
+ }
+ }
+ }
+
+ [TestMethod]
+ public void CheckNonEqual()
+ {
+ string left = ExampleHelper.GetTempFilePath();
+ string right = ExampleHelper.GetTempFilePath();
+ try
+ {
+ new BasicTable().Create(left);
+ new HelloWorld().Create(right);
+
+ string message;
+ Assert.IsFalse(ExcelDocsComparer.Compare(left, right, out message));
+ }
+ finally
+ {
+ if (File.Exists(left))
+ {
+ File.Delete(left);
+ }
+ if (File.Exists(right))
+ {
+ File.Delete(right);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/ResourceFileExtractor.cs b/ClosedXML/ClosedXML/ClosedXML_Tests/ResourceFileExtractor.cs
deleted file mode 100644
index 0083f5a..0000000
--- a/ClosedXML/ClosedXML/ClosedXML_Tests/ResourceFileExtractor.cs
+++ /dev/null
@@ -1,238 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Reflection;
-
-namespace ClosedXML_Tests
-{
- ///
- /// Summary description for ResourceFileExtractor.
- ///
- public sealed class ResourceFileExtractor
- {
- #region Static
- #region Private fields
- private static readonly Dictionary ms_defaultExtractors =
- new Dictionary();
- #endregion
- #region Public properties
- /// Instance of resource extractor for executing assembly
- public static ResourceFileExtractor Instance
- {
- get
- {
- ResourceFileExtractor _return;
- Assembly _assembly = Assembly.GetCallingAssembly();
- string _key = _assembly.GetName().FullName;
- if (!ms_defaultExtractors.TryGetValue(_key, out _return))
- {
- lock (ms_defaultExtractors)
- {
- if (!ms_defaultExtractors.TryGetValue(_key, out _return))
- {
- _return = new ResourceFileExtractor(_assembly, true, null);
- ms_defaultExtractors.Add(_key, _return);
- }
- }
- }
- return _return;
- }
- }
- #endregion
- #region Public methods
- #endregion
- #endregion
- #region Private fields
- private readonly Assembly m_assembly;
- private readonly ResourceFileExtractor m_baseExtractor;
- private readonly string m_assemblyName;
-
- private bool m_isStatic;
- private string m_resourceFilePath;
- #endregion
- #region Constructors
- ///
- /// Create instance
- ///
- /// ResourceFilePath in assembly. Example: .Properties.Scripts.
- ///
- public ResourceFileExtractor(string resourceFilePath, ResourceFileExtractor baseExtractor)
- : this(Assembly.GetCallingAssembly(), baseExtractor)
- {
- m_resourceFilePath = resourceFilePath;
- }
- ///
- /// Create instance
- ///
- ///
- public ResourceFileExtractor(ResourceFileExtractor baseExtractor)
- : this(Assembly.GetCallingAssembly(), baseExtractor)
- {
- }
- ///
- /// Create instance
- ///
- /// ResourceFilePath in assembly. Example: .Properties.Scripts.
- public ResourceFileExtractor(string resourcePath)
- : this(Assembly.GetCallingAssembly(), resourcePath)
- {
- }
- ///
- /// Instance constructor
- ///
- ///
- ///
- public ResourceFileExtractor(Assembly assembly, string resourcePath)
- : this(assembly ?? Assembly.GetCallingAssembly())
- {
- m_resourceFilePath = resourcePath;
- }
- ///
- /// Instance constructor
- ///
- public ResourceFileExtractor()
- : this(Assembly.GetCallingAssembly())
- {
- }
- ///
- /// Instance constructor
- ///
- ///
- public ResourceFileExtractor(Assembly assembly)
- : this(assembly ?? Assembly.GetCallingAssembly(), (ResourceFileExtractor) null)
- {
- }
- ///
- /// Instance constructor
- ///
- ///
- ///
- public ResourceFileExtractor(Assembly assembly, ResourceFileExtractor baseExtractor)
- : this(assembly ?? Assembly.GetCallingAssembly(), false, baseExtractor)
- {
- }
- ///
- /// Instance constructor
- ///
- ///
- ///
- ///
- /// Argument is null.
- private ResourceFileExtractor(Assembly assembly, bool isStatic, ResourceFileExtractor baseExtractor)
- {
- #region Check
- if (ReferenceEquals(assembly, null))
- {
- throw new ArgumentNullException("assembly");
- }
- #endregion
- m_assembly = assembly;
- m_baseExtractor = baseExtractor;
- m_assemblyName = Assembly.GetName().Name;
- IsStatic = isStatic;
- m_resourceFilePath = ".Resources.";
- }
- #endregion
- #region Public properties
- /// Work assembly
- public Assembly Assembly
- {
- [DebuggerStepThrough]
- get { return m_assembly; }
- }
- /// Work assembly name
- public string AssemblyName
- {
- [DebuggerStepThrough]
- get { return m_assemblyName; }
- }
- ///
- /// Path to read resource files. Example: .Resources.Upgrades.
- ///
- public string ResourceFilePath
- {
- [DebuggerStepThrough]
- get { return m_resourceFilePath; }
- [DebuggerStepThrough]
- set { m_resourceFilePath = value; }
- }
- public bool IsStatic
- {
- [DebuggerStepThrough]
- get { return m_isStatic; }
- [DebuggerStepThrough]
- set { m_isStatic = value; }
- }
- public IEnumerable GetFileNames()
- {
- string _path = AssemblyName + m_resourceFilePath;
- foreach (string _resourceName in Assembly.GetManifestResourceNames())
- {
- if (_resourceName.StartsWith(_path))
- {
- yield return _resourceName.Replace(_path, string.Empty);
- }
- }
- }
- #endregion
- #region Public methods
- public string ReadFileFromRes(string fileName)
- {
- Stream _stream = ReadFileFromResToStream(fileName);
- string _result;
- StreamReader sr = new StreamReader(_stream);
- try
- {
- _result = sr.ReadToEnd();
- }
- finally
- {
- sr.Close();
- }
- return _result;
- }
-
- public string ReadFileFromResFormat(string fileName, params object[] formatArgs)
- {
- return string.Format(ReadFileFromRes(fileName), formatArgs);
- }
-
- ///
- /// Read file in current assembly by specific path
- ///
- /// Specific path
- /// Read file name
- ///
- public string ReadSpecificFileFromRes(string specificPath, string fileName)
- {
- ResourceFileExtractor _ext = new ResourceFileExtractor(Assembly, specificPath);
- return _ext.ReadFileFromRes(fileName);
- }
- ///
- /// Read file in current assembly by specific file name
- ///
- ///
- ///
- /// ApplicationException.
- public Stream ReadFileFromResToStream(string fileName)
- {
- string _nameResFile = AssemblyName + m_resourceFilePath + fileName;
- Stream _stream = Assembly.GetManifestResourceStream(_nameResFile);
- #region Not found
- if (ReferenceEquals(_stream, null))
- {
- #region Get from base extractor
- if (!ReferenceEquals(m_baseExtractor, null))
- {
- return m_baseExtractor.ReadFileFromResToStream(fileName);
- }
- #endregion
- throw new ApplicationException("Can't find resource file " + _nameResFile);
- }
- #endregion
- return _stream;
- }
- #endregion
- }
-}
\ No newline at end of file
diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/TestHelper.cs b/ClosedXML/ClosedXML/ClosedXML_Tests/TestHelper.cs
index 10717c5..2e599de 100644
--- a/ClosedXML/ClosedXML/ClosedXML_Tests/TestHelper.cs
+++ b/ClosedXML/ClosedXML/ClosedXML_Tests/TestHelper.cs
@@ -40,13 +40,11 @@
{
string resourcePath = filePartName.Replace('\\', '.').TrimStart('.');
using (var streamExpected = _extractor.ReadFileFromResToStream(resourcePath))
+ using (var streamActual = File.OpenRead(filePath))
{
- using (var streamActual = _extractor.ReadFileFromResToStream(resourcePath))
- {
- string message;
- success = ExcelDocsComparer.Compare(streamActual, streamExpected, out message);
- Assert.IsTrue(success, message);
- }
+ string message;
+ success = ExcelDocsComparer.Compare(streamActual, streamExpected, out message);
+ Assert.IsTrue(success, message);
}
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/..svnbridge/.svnbridge b/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/..svnbridge/.svnbridge
new file mode 100644
index 0000000..88585f2
--- /dev/null
+++ b/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/..svnbridge/.svnbridge
@@ -0,0 +1 @@
+bugtraq:numbertrue
\ No newline at end of file
diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/ExcelDocsComparer.cs b/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/ExcelDocsComparer.cs
new file mode 100644
index 0000000..9def32b
--- /dev/null
+++ b/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/ExcelDocsComparer.cs
@@ -0,0 +1,41 @@
+using System;
+using System.IO;
+using System.IO.Packaging;
+
+namespace ClosedXML_Tests
+{
+ internal static class ExcelDocsComparer
+ {
+ public static bool Compare(string left, string right, out string message)
+ {
+ using (var leftStream = File.OpenRead(left))
+ {
+ using (var rightStream = File.OpenRead(right))
+ {
+ return Compare(leftStream, rightStream, out message);
+ }
+ }
+ }
+
+ public static bool Compare(Stream left, Stream right, out string message)
+ {
+ using (Package leftPackage = Package.Open(left))
+ {
+ using (Package rightPackage = Package.Open(right))
+ {
+ return PackageHelper.Compare(leftPackage, rightPackage, false, ExcludeMethod, out message);
+ }
+ }
+ }
+ private static bool ExcludeMethod(Uri uri)
+ {
+ //Exclude service data
+ if (uri.OriginalString.EndsWith(".rels") ||
+ uri.OriginalString.EndsWith(".psmdcp"))
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/PackageHelper.cs b/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/PackageHelper.cs
new file mode 100644
index 0000000..59421c4
--- /dev/null
+++ b/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/PackageHelper.cs
@@ -0,0 +1,449 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.IO.Packaging;
+using System.Linq;
+using System.Net.Mime;
+using System.Text;
+using System.Xml.Serialization;
+
+namespace ClosedXML_Tests
+{
+ public static class PackageHelper
+ {
+ public static void WriteXmlPart(Package package, Uri uri, object content, XmlSerializer serializer)
+ {
+ if (package.PartExists(uri))
+ {
+ package.DeletePart(uri);
+ }
+ var part = package.CreatePart(uri, MediaTypeNames.Text.Xml, CompressionOption.Fast);
+ using (Stream stream = part.GetStream())
+ {
+ serializer.Serialize(stream, content);
+ }
+ }
+ public static object ReadXmlPart(Package package, Uri uri, XmlSerializer serializer)
+ {
+ if (!package.PartExists(uri))
+ {
+ throw new ApplicationException(string.Format("Package part '{0}' doesn't exists!", uri.OriginalString));
+ }
+ PackagePart part = package.GetPart(uri);
+ using (Stream stream = part.GetStream())
+ {
+ return serializer.Deserialize(stream);
+ }
+ }
+
+ public static void WriteBinaryPart(Package package, Uri uri, Stream content)
+ {
+ if (package.PartExists(uri))
+ {
+ package.DeletePart(uri);
+ }
+ PackagePart part = package.CreatePart(uri, MediaTypeNames.Application.Octet, CompressionOption.Fast);
+ using (Stream stream = part.GetStream())
+ {
+ StreamHelper.StreamToStreamAppend(content, stream);
+ }
+ }
+ ///
+ /// Returns part's stream
+ ///
+ ///
+ ///
+ ///
+ public static Stream ReadBinaryPart(Package package, Uri uri)
+ {
+ if (!package.PartExists(uri))
+ {
+ throw new ApplicationException("Package part doesn't exists!");
+ }
+ PackagePart part = package.GetPart(uri);
+ return part.GetStream();
+ }
+
+ public static void CopyPart(Uri uri, Package source, Package dest)
+ {
+ CopyPart(uri, source, dest, true);
+ }
+ public static void CopyPart(Uri uri, Package source, Package dest, bool overwrite)
+ {
+ #region Check
+ if (ReferenceEquals(uri, null))
+ {
+ throw new ArgumentNullException("uri");
+ }
+ if (ReferenceEquals(source, null))
+ {
+ throw new ArgumentNullException("source");
+ }
+ if (ReferenceEquals(dest, null))
+ {
+ throw new ArgumentNullException("dest");
+ }
+ #endregion
+ if (dest.PartExists(uri))
+ {
+ if (!overwrite)
+ {
+ throw new ArgumentException("Specified part already exists", "uri");
+ }
+ dest.DeletePart(uri);
+ }
+
+ PackagePart sourcePart = source.GetPart(uri);
+ PackagePart destPart = dest.CreatePart(uri, sourcePart.ContentType, sourcePart.CompressionOption);
+
+ using (Stream sourceStream = sourcePart.GetStream())
+ {
+ using (Stream destStream = destPart.GetStream())
+ {
+ StreamHelper.StreamToStreamAppend(sourceStream, destStream);
+ }
+ }
+ }
+
+ public static void WritePart(Package package, PackagePartDescriptor descriptor, T content, Action serializeAction)
+ {
+ #region Check
+ if (ReferenceEquals(package, null))
+ {
+ throw new ArgumentNullException("package");
+ }
+ if (ReferenceEquals(descriptor, null))
+ {
+ throw new ArgumentNullException("descriptor");
+ }
+ if (ReferenceEquals(serializeAction, null))
+ {
+ throw new ArgumentNullException("serializeAction");
+ }
+ #endregion
+ if (package.PartExists(descriptor.Uri))
+ {
+ package.DeletePart(descriptor.Uri);
+ }
+ PackagePart part = package.CreatePart(descriptor.Uri, descriptor.ContentType, descriptor.CompressOption);
+ using (Stream stream = part.GetStream())
+ {
+ serializeAction(stream, content);
+ }
+ }
+ public static void WritePart(Package package, PackagePartDescriptor descriptor, Action serializeAction)
+ {
+ #region Check
+ if (ReferenceEquals(package, null))
+ {
+ throw new ArgumentNullException("package");
+ }
+ if (ReferenceEquals(descriptor, null))
+ {
+ throw new ArgumentNullException("descriptor");
+ }
+ if (ReferenceEquals(serializeAction, null))
+ {
+ throw new ArgumentNullException("serializeAction");
+ }
+ #endregion
+ if (package.PartExists(descriptor.Uri))
+ {
+ package.DeletePart(descriptor.Uri);
+ }
+ PackagePart part = package.CreatePart(descriptor.Uri, descriptor.ContentType, descriptor.CompressOption);
+ using (Stream stream = part.GetStream())
+ {
+ serializeAction(stream);
+ }
+ }
+ public static T ReadPart(Package package, Uri uri, Func deserializeFunc)
+ {
+ #region Check
+ if (ReferenceEquals(package, null))
+ {
+ throw new ArgumentNullException("package");
+ }
+ if (ReferenceEquals(uri, null))
+ {
+ throw new ArgumentNullException("uri");
+ }
+ if (ReferenceEquals(deserializeFunc, null))
+ {
+ throw new ArgumentNullException("deserializeFunc");
+ }
+ #endregion
+ if (!package.PartExists(uri))
+ {
+ throw new ApplicationException(string.Format("Package part '{0}' doesn't exists!", uri.OriginalString));
+ }
+ PackagePart part = package.GetPart(uri);
+ using (Stream stream = part.GetStream())
+ {
+ return deserializeFunc(stream);
+ }
+ }
+ public static void ReadPart(Package package, Uri uri, Action deserializeAction)
+ {
+ #region Check
+ if (ReferenceEquals(package, null))
+ {
+ throw new ArgumentNullException("package");
+ }
+ if (ReferenceEquals(uri, null))
+ {
+ throw new ArgumentNullException("uri");
+ }
+ if (ReferenceEquals(deserializeAction, null))
+ {
+ throw new ArgumentNullException("deserializeAction");
+ }
+ #endregion
+ if (!package.PartExists(uri))
+ {
+ throw new ApplicationException(string.Format("Package part '{0}' doesn't exists!", uri.OriginalString));
+ }
+ PackagePart part = package.GetPart(uri);
+ using (Stream stream = part.GetStream())
+ {
+ deserializeAction(stream);
+ }
+ }
+ public static bool TryReadPart(Package package, Uri uri, Action deserializeAction)
+ {
+ #region Check
+ if (ReferenceEquals(package, null))
+ {
+ throw new ArgumentNullException("package");
+ }
+ if (ReferenceEquals(uri, null))
+ {
+ throw new ArgumentNullException("uri");
+ }
+ if (ReferenceEquals(deserializeAction, null))
+ {
+ throw new ArgumentNullException("deserializeAction");
+ }
+ #endregion
+ if (!package.PartExists(uri))
+ {
+ return false;
+ }
+ PackagePart part = package.GetPart(uri);
+ using (Stream stream = part.GetStream())
+ {
+ deserializeAction(stream);
+ }
+ return true;
+ }
+
+ ///
+ /// Compare to packages by parts like streams
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static bool Compare(Package left, Package right, bool compareToFirstDifference, out string message)
+ {
+ return Compare(left, right, compareToFirstDifference, null, out message);
+ }
+ ///
+ /// Compare to packages by parts like streams
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static bool Compare(Package left, Package right, bool compareToFirstDifference,Func excludeMethod, out string message)
+ {
+ #region Check
+ if (left == null)
+ {
+ throw new ArgumentNullException("left");
+ }
+ if (right == null)
+ {
+ throw new ArgumentNullException("right");
+ }
+ #endregion
+ excludeMethod = excludeMethod ?? (uri => false);
+ var leftParts = left.GetParts();
+ var rightParts = right.GetParts();
+
+ var pairs = new Dictionary();
+ foreach (var part in leftParts)
+ {
+ if (excludeMethod(part.Uri))
+ {
+ continue;
+ }
+ pairs.Add(part.Uri, new PartPair(part.Uri, CompareStatus.OnlyOnLeft));
+ }
+ foreach (var part in rightParts)
+ {
+ if (excludeMethod(part.Uri))
+ {
+ continue;
+ }
+ PartPair pair;
+ if (pairs.TryGetValue(part.Uri, out pair))
+ {
+ pair.Status = CompareStatus.Equal;
+ }
+ else
+ {
+ pairs.Add(part.Uri, new PartPair(part.Uri, CompareStatus.OnlyOnRight));
+ }
+ }
+
+ if (compareToFirstDifference && pairs.Any(pair => pair.Value.Status != CompareStatus.Equal))
+ {
+ goto EXIT;
+ }
+
+ foreach (var pair in pairs.Values)
+ {
+ if (pair.Status != CompareStatus.Equal)
+ {
+ continue;
+ }
+ using (var oneStream = left.GetPart(pair.Uri).GetStream(FileMode.Open, FileAccess.Read))
+ using (var otherStream = right.GetPart(pair.Uri).GetStream(FileMode.Open, FileAccess.Read))
+ {
+ if (!StreamHelper.Compare(oneStream, otherStream))
+ {
+ pair.Status = CompareStatus.NonEqual;
+ if (compareToFirstDifference)
+ {
+ goto EXIT;
+ }
+ }
+ }
+ }
+
+ EXIT:
+ var sortedPairs = pairs.Values.ToList();
+ sortedPairs.Sort((one, other) => one.Uri.OriginalString.CompareTo(other.Uri.OriginalString));
+ var sbuilder = new StringBuilder();
+ foreach (var pair in sortedPairs)
+ {
+ if (pair.Status == CompareStatus.Equal)
+ {
+ continue;
+ }
+ sbuilder.AppendFormat("{0} :{1}", pair.Uri, pair.Status);
+ sbuilder.AppendLine();
+ }
+ message = sbuilder.ToString();
+ return message.Length == 0;
+ }
+ //--
+ #region Nested type: PackagePartDescriptor
+ public sealed class PackagePartDescriptor
+ {
+ #region Private fields
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ private readonly Uri _uri;
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ private readonly string _contentType;
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ private readonly CompressionOption _compressOption;
+ #endregion
+ #region Constructor
+ ///
+ /// Instance constructor
+ ///
+ /// Part uri
+ /// Content type from
+ ///
+ public PackagePartDescriptor(Uri uri, string contentType, CompressionOption compressOption)
+ {
+ #region Check
+ if (ReferenceEquals(uri, null))
+ {
+ throw new ArgumentNullException("uri");
+ }
+ if (string.IsNullOrEmpty(contentType))
+ {
+ throw new ArgumentNullException("contentType");
+ }
+ #endregion
+ _uri = uri;
+ _contentType = contentType;
+ _compressOption = compressOption;
+ }
+ #endregion
+ #region Public properties
+ public Uri Uri
+ {
+ [DebuggerStepThrough]
+ get { return _uri; }
+ }
+ public string ContentType
+ {
+ [DebuggerStepThrough]
+ get { return _contentType; }
+ }
+ public CompressionOption CompressOption
+ {
+ [DebuggerStepThrough]
+ get { return _compressOption; }
+ }
+ #endregion
+ #region Public methods
+ public override string ToString()
+ {
+ return string.Format("Uri:{0} ContentType: {1}, Compression: {2}", _uri, _contentType, _compressOption);
+ }
+ #endregion
+ }
+ #endregion
+ #region Nested type: CompareStatus
+ private enum CompareStatus
+ {
+ OnlyOnLeft,
+ OnlyOnRight,
+ Equal,
+ NonEqual
+ }
+ #endregion
+ #region Nested type: PartPair
+ private sealed class PartPair
+ {
+ #region Private fields
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ private readonly Uri _uri;
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ private CompareStatus _status;
+ #endregion
+ #region Constructor
+ public PartPair(Uri uri, CompareStatus status)
+ {
+ _uri = uri;
+ _status = status;
+ }
+ #endregion
+ #region Public properties
+ public Uri Uri
+ {
+ [DebuggerStepThrough]
+ get { return _uri; }
+ }
+ public CompareStatus Status
+ {
+ [DebuggerStepThrough]
+ get { return _status; }
+ [DebuggerStepThrough]
+ set { _status = value; }
+ }
+ #endregion
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/ResourceFileExtractor.cs b/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/ResourceFileExtractor.cs
new file mode 100644
index 0000000..0083f5a
--- /dev/null
+++ b/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/ResourceFileExtractor.cs
@@ -0,0 +1,238 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+
+namespace ClosedXML_Tests
+{
+ ///
+ /// Summary description for ResourceFileExtractor.
+ ///
+ public sealed class ResourceFileExtractor
+ {
+ #region Static
+ #region Private fields
+ private static readonly Dictionary ms_defaultExtractors =
+ new Dictionary();
+ #endregion
+ #region Public properties
+ /// Instance of resource extractor for executing assembly
+ public static ResourceFileExtractor Instance
+ {
+ get
+ {
+ ResourceFileExtractor _return;
+ Assembly _assembly = Assembly.GetCallingAssembly();
+ string _key = _assembly.GetName().FullName;
+ if (!ms_defaultExtractors.TryGetValue(_key, out _return))
+ {
+ lock (ms_defaultExtractors)
+ {
+ if (!ms_defaultExtractors.TryGetValue(_key, out _return))
+ {
+ _return = new ResourceFileExtractor(_assembly, true, null);
+ ms_defaultExtractors.Add(_key, _return);
+ }
+ }
+ }
+ return _return;
+ }
+ }
+ #endregion
+ #region Public methods
+ #endregion
+ #endregion
+ #region Private fields
+ private readonly Assembly m_assembly;
+ private readonly ResourceFileExtractor m_baseExtractor;
+ private readonly string m_assemblyName;
+
+ private bool m_isStatic;
+ private string m_resourceFilePath;
+ #endregion
+ #region Constructors
+ ///
+ /// Create instance
+ ///
+ /// ResourceFilePath in assembly. Example: .Properties.Scripts.
+ ///
+ public ResourceFileExtractor(string resourceFilePath, ResourceFileExtractor baseExtractor)
+ : this(Assembly.GetCallingAssembly(), baseExtractor)
+ {
+ m_resourceFilePath = resourceFilePath;
+ }
+ ///
+ /// Create instance
+ ///
+ ///
+ public ResourceFileExtractor(ResourceFileExtractor baseExtractor)
+ : this(Assembly.GetCallingAssembly(), baseExtractor)
+ {
+ }
+ ///
+ /// Create instance
+ ///
+ /// ResourceFilePath in assembly. Example: .Properties.Scripts.
+ public ResourceFileExtractor(string resourcePath)
+ : this(Assembly.GetCallingAssembly(), resourcePath)
+ {
+ }
+ ///
+ /// Instance constructor
+ ///
+ ///
+ ///
+ public ResourceFileExtractor(Assembly assembly, string resourcePath)
+ : this(assembly ?? Assembly.GetCallingAssembly())
+ {
+ m_resourceFilePath = resourcePath;
+ }
+ ///
+ /// Instance constructor
+ ///
+ public ResourceFileExtractor()
+ : this(Assembly.GetCallingAssembly())
+ {
+ }
+ ///
+ /// Instance constructor
+ ///
+ ///
+ public ResourceFileExtractor(Assembly assembly)
+ : this(assembly ?? Assembly.GetCallingAssembly(), (ResourceFileExtractor) null)
+ {
+ }
+ ///
+ /// Instance constructor
+ ///
+ ///
+ ///
+ public ResourceFileExtractor(Assembly assembly, ResourceFileExtractor baseExtractor)
+ : this(assembly ?? Assembly.GetCallingAssembly(), false, baseExtractor)
+ {
+ }
+ ///
+ /// Instance constructor
+ ///
+ ///
+ ///
+ ///
+ /// Argument is null.
+ private ResourceFileExtractor(Assembly assembly, bool isStatic, ResourceFileExtractor baseExtractor)
+ {
+ #region Check
+ if (ReferenceEquals(assembly, null))
+ {
+ throw new ArgumentNullException("assembly");
+ }
+ #endregion
+ m_assembly = assembly;
+ m_baseExtractor = baseExtractor;
+ m_assemblyName = Assembly.GetName().Name;
+ IsStatic = isStatic;
+ m_resourceFilePath = ".Resources.";
+ }
+ #endregion
+ #region Public properties
+ /// Work assembly
+ public Assembly Assembly
+ {
+ [DebuggerStepThrough]
+ get { return m_assembly; }
+ }
+ /// Work assembly name
+ public string AssemblyName
+ {
+ [DebuggerStepThrough]
+ get { return m_assemblyName; }
+ }
+ ///
+ /// Path to read resource files. Example: .Resources.Upgrades.
+ ///
+ public string ResourceFilePath
+ {
+ [DebuggerStepThrough]
+ get { return m_resourceFilePath; }
+ [DebuggerStepThrough]
+ set { m_resourceFilePath = value; }
+ }
+ public bool IsStatic
+ {
+ [DebuggerStepThrough]
+ get { return m_isStatic; }
+ [DebuggerStepThrough]
+ set { m_isStatic = value; }
+ }
+ public IEnumerable GetFileNames()
+ {
+ string _path = AssemblyName + m_resourceFilePath;
+ foreach (string _resourceName in Assembly.GetManifestResourceNames())
+ {
+ if (_resourceName.StartsWith(_path))
+ {
+ yield return _resourceName.Replace(_path, string.Empty);
+ }
+ }
+ }
+ #endregion
+ #region Public methods
+ public string ReadFileFromRes(string fileName)
+ {
+ Stream _stream = ReadFileFromResToStream(fileName);
+ string _result;
+ StreamReader sr = new StreamReader(_stream);
+ try
+ {
+ _result = sr.ReadToEnd();
+ }
+ finally
+ {
+ sr.Close();
+ }
+ return _result;
+ }
+
+ public string ReadFileFromResFormat(string fileName, params object[] formatArgs)
+ {
+ return string.Format(ReadFileFromRes(fileName), formatArgs);
+ }
+
+ ///
+ /// Read file in current assembly by specific path
+ ///
+ /// Specific path
+ /// Read file name
+ ///
+ public string ReadSpecificFileFromRes(string specificPath, string fileName)
+ {
+ ResourceFileExtractor _ext = new ResourceFileExtractor(Assembly, specificPath);
+ return _ext.ReadFileFromRes(fileName);
+ }
+ ///
+ /// Read file in current assembly by specific file name
+ ///
+ ///
+ ///
+ /// ApplicationException.
+ public Stream ReadFileFromResToStream(string fileName)
+ {
+ string _nameResFile = AssemblyName + m_resourceFilePath + fileName;
+ Stream _stream = Assembly.GetManifestResourceStream(_nameResFile);
+ #region Not found
+ if (ReferenceEquals(_stream, null))
+ {
+ #region Get from base extractor
+ if (!ReferenceEquals(m_baseExtractor, null))
+ {
+ return m_baseExtractor.ReadFileFromResToStream(fileName);
+ }
+ #endregion
+ throw new ApplicationException("Can't find resource file " + _nameResFile);
+ }
+ #endregion
+ return _stream;
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/StreamHelper.cs b/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/StreamHelper.cs
new file mode 100644
index 0000000..81c842a
--- /dev/null
+++ b/ClosedXML/ClosedXML/ClosedXML_Tests/Utils/StreamHelper.cs
@@ -0,0 +1,139 @@
+using System;
+using System.IO;
+
+namespace ClosedXML_Tests
+{
+ ///
+ /// Help methods for work with streams
+ ///
+ public static class StreamHelper
+ {
+ ///
+ /// Convert stream to byte array
+ ///
+ /// Stream
+ /// Byte array
+ public static byte[] StreamToArray(Stream pStream)
+ {
+ long iLength = pStream.Length;
+ byte[] bytes = new byte[iLength];
+ for (int i = 0; i < iLength; i++)
+ {
+ bytes[i] = (byte) pStream.ReadByte();
+ }
+ pStream.Close();
+ return bytes;
+ }
+ ///
+ /// Convert byte array to stream
+ ///
+ /// Byte array
+ /// Open stream
+ ///
+ public static Stream ArrayToStreamAppend(byte[] pBynaryArray, Stream pStream)
+ {
+ #region Check params
+ if (ReferenceEquals(pBynaryArray, null))
+ {
+ throw new ArgumentNullException("pBynaryArray");
+ }
+ if (ReferenceEquals(pStream, null))
+ {
+ throw new ArgumentNullException("pStream");
+ }
+ if (!pStream.CanWrite)
+ {
+ throw new ArgumentException("Can't write to stream", "pStream");
+ }
+ #endregion
+ foreach (byte b in pBynaryArray)
+ {
+ pStream.WriteByte(b);
+ }
+ return pStream;
+ }
+
+ public static void StreamToStreamAppend(Stream streamIn, Stream streamToWrite)
+ {
+ StreamToStreamAppend(streamIn, streamToWrite, 0);
+ }
+ public static void StreamToStreamAppend(Stream streamIn, Stream streamToWrite, long dataLength)
+ {
+ #region Check params
+ if (ReferenceEquals(streamIn, null))
+ {
+ throw new ArgumentNullException("streamIn");
+ }
+ if (ReferenceEquals(streamToWrite, null))
+ {
+ throw new ArgumentNullException("streamToWrite");
+ }
+ if (!streamIn.CanRead)
+ {
+ throw new ArgumentException("Can't read from stream", "streamIn");
+ }
+ if (!streamToWrite.CanWrite)
+ {
+ throw new ArgumentException("Can't write to stream", "streamToWrite");
+ }
+ #endregion
+ byte[] buf = new byte[512];
+ long length;
+ if (dataLength == 0)
+ {
+ length = streamIn.Length - streamIn.Position;
+ }
+ else
+ {
+ length = dataLength;
+ }
+ long rest = length;
+ while (rest > 0)
+ {
+ int len1 = streamIn.Read(buf, 0, rest >= 512 ? 512 : (int) rest);
+ streamToWrite.Write(buf, 0, len1);
+ rest -= len1;
+ }
+ }
+
+ ///
+ /// Compare two streams by looping
+ ///
+ ///
+ ///
+ ///
+ public static bool Compare(Stream one, Stream other)
+ {
+ #region Check
+ if (one == null)
+ {
+ throw new ArgumentNullException("one");
+ }
+ if (other == null)
+ {
+ throw new ArgumentNullException("other");
+ }
+ if (one.Position != 0)
+ {
+ throw new ArgumentException("Must be in position 0", "one");
+ }
+ if (other.Position != 0)
+ {
+ throw new ArgumentException("Must be in position 0", "other");
+ }
+ #endregion
+ if (one.Length != other.Length)
+ {
+ return false;
+ }
+ int _oneByte;
+ int _otherByte;
+ do
+ {
+ _oneByte = one.ReadByte();
+ _otherByte = other.ReadByte();
+ } while (_oneByte == _otherByte && !(_oneByte == -1 || _otherByte == -1));
+ return _oneByte == -1 && _otherByte == -1;
+ }
+ }
+}
\ No newline at end of file