SPRNET-691

This commit is contained in:
eeichinger
2009-08-02 20:24:20 +00:00
parent 37787ef76e
commit e44e460143
15 changed files with 20627 additions and 6 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,145 @@
#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.IO;
using System.Text;
using Spring.Util;
namespace Spring.Core.IO
{
/// <summary>
/// Holder that combines <see cref="IResource" /> with a specific encoding to be used for reading
/// from the resource
/// </summary>
/// <author>Juergen Hoeller</author>
/// <author>Erich Eichinger (.NET)</author>
public class EncodedResource
{
private readonly IResource resource;
private readonly Encoding encoding;
private readonly bool autoDetectEncoding;
/// <summary>
/// Create an encoded resource, autodetecting the encoding from the resource stream.
/// </summary>
/// <param name="resource"></param>
public EncodedResource(IResource resource)
:this(resource, null, true)
{
// noop
}
/// <summary>
/// Create an encoded resource, autodetecting the encoding from the resource stream.
/// </summary>
/// <param name="resource">the resource to read from. Must not be <c>null</c></param>
/// <param name="autoDetectEncoding">whether to autoDetect encoding from byte-order marks (<see cref="StreamReader(Stream, Encoding, bool)"/>)</param>
public EncodedResource(IResource resource, bool autoDetectEncoding)
:this(resource, null, autoDetectEncoding)
{
// noop
}
/// <summary>
/// Create an encoded resource using the specified encoding.
/// </summary>
/// <param name="resource">the resource to read from. Must not be <c>null</c></param>
/// <param name="encoding">the encoding to use. If <c>null</c>, encoding will be autodetected.</param>
/// <param name="autoDetectEncoding">whether to autoDetect encoding from byte-order marks (<see cref="StreamReader(Stream, Encoding, bool)"/>)</param>
public EncodedResource(IResource resource, Encoding encoding, bool autoDetectEncoding)
{
AssertUtils.ArgumentNotNull(resource, "resource");
this.resource = resource;
this.encoding = encoding;
this.autoDetectEncoding = autoDetectEncoding;
}
/// <summary>
/// Get the underlying resource
/// </summary>
public IResource Resource
{
get { return resource; }
}
/// <summary>
/// Get the encoding to use for reading, if any. May be <c>null</c>
/// </summary>
public Encoding Encoding
{
get { return encoding; }
}
/// <summary>
/// whether to autoDetect encoding from byte-order marks (<see cref="StreamReader(Stream, Encoding, bool)"/>)
/// </summary>
public bool AutoDetectEncoding
{
get { return autoDetectEncoding; }
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public TextReader OpenReader()
{
if (this.encoding != null)
{
return new StreamReader(this.resource.InputStream, this.encoding, autoDetectEncoding);
}
return new StreamReader(this.resource.InputStream, autoDetectEncoding);
}
/// <summary>
/// Determine whether <paramref name="obj"/> equals this instance.
/// </summary>
/// <returns>
/// <c>true</c> if obj is an <see cref="EncodedResource"/> and both
/// , <see cref="Resource"/> and <see cref="Encoding"/> are equal.
/// </returns>
public override bool Equals(object obj)
{
if (obj == this) return true;
if (!(obj is EncodedResource)) return false;
EncodedResource other = (EncodedResource) obj;
return object.Equals(this.resource, other.resource)
&& object.Equals(this.encoding, other.encoding);
}
/// <summary>
/// Calculate the unique hash code for this instance.
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return this.resource.GetHashCode();
}
/// <summary>
/// Get a textual description of the resource.
/// </summary>
public override string ToString()
{
return this.resource.ToString();
}
}
}

View File

@@ -1,7 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>9.0.21022</ProductVersion>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{710961A3-0DF4-49E4-A26E-F5B9C044AC84}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -271,6 +271,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Core\Conventions.cs" />
<Compile Include="Core\IO\EncodedResource.cs" />
<Compile Include="Core\MethodArgumentsCriteria.cs" />
<Compile Include="Core\IO\AbstractResource.cs" />
<Compile Include="Core\IO\AssemblyResource.cs" />

View File

@@ -174,5 +174,38 @@ namespace Spring.Util
return sb.ToString();
}
/// <summary>
/// Concatenates 2 arrays of compatible element types
/// </summary>
/// <remarks>
/// If either of the arguments is null, the other array is returned as the result.
/// The array element types may differ as long as they are assignable. The result array will be of the "smaller" element type.
/// </remarks>
public static Array Concat(Array first, Array second)
{
if (first == null) return second;
if (second == null) return first;
Type resultElementType;
Type firstElementType = first.GetType().GetElementType();
Type secondElementType = second.GetType().GetElementType();
if (firstElementType.IsAssignableFrom(secondElementType))
{
resultElementType = firstElementType;
}
else if (secondElementType.IsAssignableFrom(firstElementType))
{
resultElementType = secondElementType;
}
else
{
throw new ArgumentException(string.Format("Array element types '{0}' and '{1}' are not compatible", firstElementType, secondElementType));
}
Array result = Array.CreateInstance(resultElementType, first.Length + second.Length);
Array.Copy( first, result, first.Length );
Array.Copy(second, 0, result, first.Length, second.Length);
return result;
}
}
}

View File

@@ -37,6 +37,26 @@ namespace Spring.Util
/// <author>Mark Pollack (.NET)</author>
public sealed class CollectionUtils
{
/// <summary>
/// Checks if the given array or collection has elements and none of the elements is null.
/// </summary>
/// <param name="collection">the collection to be checked.</param>
/// <returns>true if the collection has a length and contains only non-null elements.</returns>
public static bool HasElements(ICollection collection)
{
return ArrayUtils.HasElements(collection);
}
/// <summary>
/// Checks if the given array or collection is null or has no elements.
/// </summary>
/// <param name="collection"></param>
/// <returns></returns>
public static bool HasLength(ICollection collection)
{
return ArrayUtils.HasLength(collection);
}
/// <summary>
/// Determine whether a given collection only contains
/// a single unique object

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{ED204A7B-832F-44C7-BFE3-504AEBE1BCC8}</ProjectGuid>
<OutputType>Library</OutputType>
@@ -48,6 +48,8 @@
<Link>CommonAssemblyInfo.cs</Link>
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Testing\Ado\IPlatformTransaction.cs" />
<Compile Include="Testing\Ado\SimpleAdoTestUtils.cs" />
<Compile Include="Testing\NUnit\AbstractDependencyInjectionSpringContextTests.cs" />
<Compile Include="Testing\NUnit\AbstractSpringContextTests.cs" />
<Compile Include="Testing\NUnit\AbstractTransactionalDbProviderSpringContextTests.cs" />

View File

@@ -0,0 +1,27 @@
using System;
namespace Spring.Testing.Ado
{
/// <summary>
/// Holds status for an active transaction. You *must* dispose this object!
/// </summary>
/// <remarks>
/// <example>
/// Usage Pattern:
/// <code>
/// TBD
/// </code>
/// </example>
/// </remarks>
public interface IPlatformTransaction : IDisposable
{
/// <summary>
/// Mark transaction for commit on disposal
/// </summary>
void Commit();
/// <summary>
/// Throw exception and rollback any uncommitted commands
/// </summary>
void Rollback();
}
}

View File

@@ -0,0 +1,321 @@
#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.Data;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using Common.Logging;
using Spring.Core.IO;
using Spring.Dao;
using Spring.Data;
using Spring.Data.Common;
using Spring.Data.Core;
using Spring.Transaction;
using Spring.Util;
namespace Spring.Testing.Ado
{
/// <summary>
/// TBD
/// </summary>
/// <author>Erich Eichinger</author>
public class SimpleAdoTestUtils
{
private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly RegexOptions REGEX_OPTIONS = RegexOptions.Multiline | RegexOptions.ECMAScript | RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase;
/// <summary>
/// TBD
/// </summary>
public static readonly string BLOCKDELIM_GO = @"^[\s\n\r]*GO[\s\n\r]*$";
/// <summary>
/// TBD
/// </summary>
public static readonly Regex BLOCKDELIM_GO_EXP = new Regex(BLOCKDELIM_GO, REGEX_OPTIONS);
/// <summary>
/// TBD
/// </summary>
public static readonly string BLOCKDELIM_SEMICOLON = @";";
/// <summary>
/// TBD
/// </summary>
public static readonly Regex BLOCKDELIM_SEMICOLON_EXP = new Regex(BLOCKDELIM_SEMICOLON, REGEX_OPTIONS);
/// <summary>
/// TBD
/// </summary>
public static readonly string BLOCKDELIM_NEWLINE = @"\n";
/// <summary>
/// TBD
/// </summary>
public static readonly Regex BLOCKDELIM_NEWLINE_EXP = new Regex(BLOCKDELIM_NEWLINE, REGEX_OPTIONS);
/// <summary>
/// TBD
/// </summary>
public static Regex BLOCKDELIM_DEFAULT_EXP = BLOCKDELIM_GO_EXP;
/// <summary>
/// TBD
/// </summary>
public static Regex[] BLOCKDELIM_ALL_EXP = { BLOCKDELIM_GO_EXP, BLOCKDELIM_SEMICOLON_EXP, BLOCKDELIM_NEWLINE_EXP };
static SimpleAdoTestUtils()
{ }
/// <summary>
/// TBD
/// </summary>
public static IPlatformTransaction CreateTransaction(IDbProvider dbProvider, ITransactionDefinition txDefinition)
{
AdoPlatformTransactionManager txMgr = new AdoPlatformTransactionManager(dbProvider);
ITransactionStatus txStatus = txMgr.GetTransaction(txDefinition);
return new PlatformTransactionHolder(txStatus, txMgr);
}
/// <summary>
/// Execute the given script
/// </summary>
public static void ExecuteSqlScript(AdoTemplate adoTemplate, string script, params Regex[] blockDelimiter)
{
ExecuteSqlScriptInternal(adoTemplate, new EncodedResource(new StringResource(script)), false, blockDelimiter);
}
/// <summary>
/// Execute the given script
/// </summary>
public static void ExecuteSqlScript(IAdoOperations adoTemplate, IResourceLoader resourceLoader, string scriptResourcePath, bool continueOnError, params Regex[] blockDelimiter)
{
ExecuteSqlScriptInternal(adoTemplate, new EncodedResource(resourceLoader.GetResource(scriptResourcePath)), continueOnError, blockDelimiter);
}
/// <summary>
/// Execute the given script
/// </summary>
public static void ExecuteSqlScript(IAdoOperations adoTemplate, IResource resource, bool continueOnError, params Regex[] blockDelimiter)
{
ExecuteSqlScriptInternal(adoTemplate, new EncodedResource(resource), continueOnError, blockDelimiter);
}
/// <summary>
/// Execute the given script
/// </summary>
public static void ExecuteSqlScript(IAdoOperations adoTemplate, EncodedResource resource, bool continueOnError, params Regex[] blockDelimiter)
{
ExecuteSqlScriptInternal(adoTemplate, resource, continueOnError, blockDelimiter);
}
/// <summary>
/// Execute the given script
/// </summary>
private static void ExecuteSqlScriptInternal(IAdoOperations adoTemplate, EncodedResource resource, bool continueOnError, params Regex[] blockDelimiter)
{
AssertUtils.ArgumentNotNull(adoTemplate, "adoTemplate");
AssertUtils.ArgumentNotNull(resource, "resource");
if (!CollectionUtils.HasElements(blockDelimiter))
{
blockDelimiter = BLOCKDELIM_ALL_EXP;
}
ArrayList statements = new ArrayList();
try
{
GetScriptBlocks(resource, statements, blockDelimiter);
}
catch (Exception ex)
{
throw new DataAccessResourceFailureException("Failed to open SQL script from " + resource, ex);
}
foreach (string statement in statements)
{
try
{
adoTemplate.ExecuteNonQuery(CommandType.Text, statement);
}
catch (DataAccessException dae)
{
if (!continueOnError)
{
throw;
}
Log.Warn(string.Format("SQL statement failed:{0}", statement), dae);
}
}
}
/// <summary>
/// TBD
/// </summary>
public static void GetScriptBlocks(EncodedResource encodedResource, IList blockCollector, params Regex[] blockDelimiterPatterns)
{
AssertUtils.ArgumentNotNull(blockCollector, "blockCollector");
using (TextReader sr = encodedResource.OpenReader())
{
string script = sr.ReadToEnd();
// the first pattern that finds a match will be used, if any
Regex patternToUse = BLOCKDELIM_DEFAULT_EXP;
if (blockDelimiterPatterns != null)
{
foreach (Regex pattern in blockDelimiterPatterns)
{
if (pattern.IsMatch(script))
{
patternToUse = pattern;
break;
}
}
}
Split(script, patternToUse, blockCollector);
}
}
private static void Split(string text, Regex exp, IList blockCollector)
{
// string[] blocks = exp.Split(text);
// foreach(string block in blocks)
// {
// if (StringUtils.HasText(block))
// {
// blockCollector.Add(block);
// }
// }
MatchCollection matches = exp.Matches(text);
int curIndexStart = 0;
string tmp;
for (int i = 0; i < matches.Count; i++)
{
Match match = matches[i];
Group group = match.Groups[0];
// Capture cap = group.Captures[0];
tmp = text.Substring(curIndexStart, match.Index - curIndexStart);
if (tmp.Trim().Length > 0)
blockCollector.Add(tmp);
curIndexStart = match.Index + match.Length;
}
tmp = text.Substring(curIndexStart);
if (tmp.Trim().Length > 0)
blockCollector.Add(tmp);
}
#region To be probably added in a future version
// public static void ExecuteSqlScript( AdoTemplate adoTemplate, IResource scriptResource, string blockDelimiter, bool continueOnError )
// {
// ExecuteSqlScript( adoTemplate, new EncodedResource(scriptResource), new Regex( Regex.Escape(blockDelimiter), REGEX_OPTIONS ), continueOnError );
// }
//
// public static void ExecuteSqlScript( AdoTemplate adoTemplate, EncodedResource resource, string blockDelimiter, bool continueOnError )
// {
// ExecuteSqlScript( adoTemplate, resource, new Regex( Regex.Escape(blockDelimiter), REGEX_OPTIONS ), continueOnError );
// }
// /// <summary>
// /// Execute the given script
// /// </summary>
// public static void ExecuteSqlScript(AdoTemplate adoTemplate, string script, params string[] blockDelimiter)
// {
// Regex[] exps = CreateRegexpsFromStrings(blockDelimiter);
// ExecuteSqlScriptInternal(adoTemplate, new EncodedResource(new StringResource(script)), false, exps);
// }
// /// <summary>
// /// Creates an array of <see cref="Regex"/> from the given <paramref name="blockDelimiter"/>
// /// </summary>
// private static Regex[] CreateRegexpsFromStrings(string[] blockDelimiter)
// {
// Regex[] exps = null;
// if (!CollectionUtils.IsEmpty(blockDelimiter))
// {
// ArrayList expsList = new ArrayList();
// foreach (string delim in blockDelimiter)
// {
// expsList.Add(new Regex(Regex.Escape(delim), REGEX_OPTIONS));
// }
// exps = (Regex[])expsList.ToArray(typeof(Regex));
// }
// return exps;
// }
//
#endregion
private class PlatformTransactionHolder : IPlatformTransaction
{
private ITransactionStatus txStatus;
private IPlatformTransactionManager txMgr;
private bool commit;
public PlatformTransactionHolder(ITransactionStatus txStatus, IPlatformTransactionManager txMgr)
{
AssertUtils.ArgumentNotNull(txStatus, "txStatus");
AssertUtils.ArgumentNotNull(txMgr, "txMgr");
this.txStatus = txStatus;
this.txMgr = txMgr;
this.commit = false;
}
public void Dispose()
{
try
{
if (txStatus == null)
return;
if (commit)
{
txMgr.Commit(txStatus);
return;
}
txMgr.Rollback(txStatus);
}
finally
{
txMgr = null;
txStatus = null;
}
}
public void Commit()
{
commit = true;
}
public void Rollback()
{
try
{
txMgr.Rollback(txStatus);
}
finally
{
txStatus = null;
}
}
}
}
}

View File

@@ -1,8 +1,8 @@
using System;
using System.Data;
using Spring.Data;
using Spring.Data.Common;
using Spring.Data.Core;
using Spring.Testing.Ado;
namespace Spring.Testing.NUnit
{
@@ -98,8 +98,16 @@ namespace Spring.Testing.NUnit
return (int) adoTemplate.ExecuteScalar(CommandType.Text, "SELECT COUNT(0) FROM " + tableName);
}
//TODO ExecuteScript...
/// <summary>
/// Execute the given SQL script using
/// <see cref="SimpleAdoTestUtils.ExecuteSqlScript(Spring.Data.IAdoOperations,Spring.Core.IO.IResourceLoader,string,bool,System.Text.RegularExpressions.Regex[])"/>
/// </summary>
/// <param name="scriptResourcePath"></param>
/// <param name="continueOnError"></param>
protected void ExecuteSqlScript(string scriptResourcePath, bool continueOnError)
{
SimpleAdoTestUtils.ExecuteSqlScript( this.AdoTemplate, this.applicationContext, scriptResourcePath, continueOnError);
}
}
}

View File

@@ -0,0 +1,97 @@
#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.IO;
using System.Text;
using NUnit.Framework;
using Spring.Util;
namespace Spring.Core.IO
{
/// <summary>
/// </summary>
/// <author>Erich Eichinger</author>
[TestFixture]
public class EncodedResourceTests
{
[Test]
public void HashcodeIsCalculatedUsingResourceOnly()
{
StringResource testResource = new StringResource("test");
EncodedResource er1 = new EncodedResource(testResource, Encoding.ASCII, true);
EncodedResource er2 = new EncodedResource(testResource, Encoding.UTF32, false);
Assert.AreEqual(testResource.GetHashCode(), er1.GetHashCode());
Assert.AreEqual(er1.GetHashCode(), er2.GetHashCode());
}
[Test]
public void OpensReaderWithDefaults()
{
EncodedResource r = new EncodedResource( new StringResource("test") );
StreamReader reader = (StreamReader)r.OpenReader();
Assert.AreEqual(Encoding.UTF8, reader.CurrentEncoding);
Assert.AreEqual("test", reader.ReadToEnd());
}
[Test]
public void OpensReaderWithAutoDetectEncoding()
{
string expected = "test";
Encoding utf32 = new UTF32Encoding(false, true);
byte[] resourceData = GetBytes(expected, utf32);
resourceData = (byte[])ArrayUtils.Concat(utf32.GetPreamble(), resourceData);
EncodedResource r = new EncodedResource( new InputStreamResource( new MemoryStream( resourceData), "description" ), Encoding.UTF8, true);
StreamReader reader = (StreamReader)r.OpenReader();
Assert.AreEqual(Encoding.UTF8, reader.CurrentEncoding);
string actual = reader.ReadToEnd();
Assert.AreEqual( "\uFEFF" + expected , actual);
// interestingly the line below is *not* true!
// Assert.AreEqual(utf32.GetString(resourceData), actual);
Assert.AreEqual(utf32, reader.CurrentEncoding);
}
[Test]
public void OpensReaderWithoutAutoDetectEncoding()
{
string expected = "test";
Encoding utf32 = new UTF32Encoding(false, true);
byte[] resourceData = GetBytes(expected, utf32);
EncodedResource r = new EncodedResource(new InputStreamResource(new MemoryStream(resourceData), "description"), Encoding.UTF8, false);
StreamReader reader = (StreamReader)r.OpenReader();
Assert.AreEqual(Encoding.UTF8, reader.CurrentEncoding);
string actual = reader.ReadToEnd();
// Assert.AreEqual("\uFFFD\uFFFD\0\0t\0\0\0e\0\0\0s\0\0\0t\0\0\0", actual);
Assert.AreEqual(Encoding.UTF8.GetString(resourceData), actual);
Assert.AreEqual(Encoding.UTF8, reader.CurrentEncoding);
}
/// <summary>
/// Returns the text bytes including the encoding's preamble (<see cref="Encoding.GetPreamble"/>), if any.
/// </summary>
private byte[] GetBytes(string text, Encoding encoding)
{
byte[] resourceData = encoding.GetBytes(text);
resourceData = (byte[])ArrayUtils.Concat(encoding.GetPreamble(), resourceData);
return resourceData;
}
}
}

View File

@@ -1,7 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>9.0.21022</ProductVersion>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -229,6 +229,7 @@
<Compile Include="Core\ControlFlowFactoryTests.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Core\IO\EncodedResourceTests.cs" />
<Compile Include="Core\MethodArgumentsCriteriaTests.cs" />
<Compile Include="Core\IO\AssemblyResourceTest.cs" />
<Compile Include="Core\IO\ConfigSectionResourceTests.cs" />

View File

@@ -64,5 +64,22 @@ namespace Spring.Util
Assert.IsFalse(ArrayUtils.HasLength(new byte[0]));
Assert.IsTrue(ArrayUtils.HasLength(new byte[1]));
}
[Test]
public void ConcatsArrays()
{
byte[] array1 = new byte[] { 0, 1, 2, 3};
byte[] array2 = new byte[] { 4, 5, 6, 7};
byte[] result = (byte[])ArrayUtils.Concat(array1, array2);
Assert.AreEqual( new byte[] { 0,1,2,3,4,5,6,7 }, result );
}
[Test]
public void ConcatsNullArrays()
{
byte[] array = new byte[] { 0, 1, 2, 3};
Assert.AreEqual(new byte[] { 0, 1, 2, 3 }, ArrayUtils.Concat(array, null));
Assert.AreEqual(new byte[] { 0, 1, 2, 3 }, ArrayUtils.Concat(null, array));
}
}
}

View File

@@ -39,12 +39,17 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\Net\2.0\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="Rhino.Mocks, Version=3.4.0.0, Culture=neutral, PublicKeyToken=0b3305902db7183f, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\Net\2.0\Rhino.Mocks.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Testing\Ado\SimpleAdoTestUtilsTests.cs" />
<Compile Include="Testing\NUnit\AbstractDependencyInjectionSpringContextTestsTests.cs" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,150 @@
#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.Data;
using NUnit.Framework;
using Rhino.Mocks;
using Spring.Core.IO;
using Spring.Data;
using Spring.Data.Common;
using Spring.Data.Core;
using Spring.Transaction.Support;
namespace Spring.Testing.Ado
{
/// <summary>
/// </summary>
/// <author>Erich Eichinger</author>
[TestFixture]
public class SimpleAdoTestUtilsTests
{
private MockRepository mocks;
private IAdoOperations adoTemplate;
[SetUp]
public void SetUp()
{
mocks = new MockRepository();
adoTemplate = (IAdoOperations) mocks.CreateMock(typeof (IAdoOperations));
}
[Test]
public void ExecuteEmptyScript()
{
IResource scriptResource = new StringResource("");
mocks.ReplayAll();
SimpleAdoTestUtils.ExecuteSqlScript(adoTemplate, scriptResource, false, SimpleAdoTestUtils.BLOCKDELIM_GO_EXP);
mocks.VerifyAll();
}
[Test]
public void ExecuteSingleStatement()
{
IResource scriptResource = new StringResource("statement 1");
Expect.Call(adoTemplate.ExecuteNonQuery(CommandType.Text, "statement 1")).Return(0);
mocks.ReplayAll();
SimpleAdoTestUtils.ExecuteSqlScript(adoTemplate, scriptResource, false, SimpleAdoTestUtils.BLOCKDELIM_GO_EXP);
mocks.VerifyAll();
}
[Test]
public void ExecuteScriptWithGOBlocks()
{
IResource scriptResource = new StringResource("\tstatement 1 \n\n\t GO\t \n statement 2\nGO");
Expect.Call(adoTemplate.ExecuteNonQuery(CommandType.Text, "\tstatement 1 \n")).Return(0);
Expect.Call(adoTemplate.ExecuteNonQuery(CommandType.Text, "\n statement 2\n")).Return(0);
mocks.ReplayAll();
SimpleAdoTestUtils.ExecuteSqlScript(adoTemplate, scriptResource, false, SimpleAdoTestUtils.BLOCKDELIM_GO_EXP);
mocks.VerifyAll();
}
[Test]
public void ExecuteScriptWithSemicolonSeparatedStatements()
{
IResource scriptResource = new StringResource("\tstatement 1 ;\nGO\n statement 2;");
Expect.Call(adoTemplate.ExecuteNonQuery(CommandType.Text, "\tstatement 1 ")).Return(0);
Expect.Call(adoTemplate.ExecuteNonQuery(CommandType.Text, "\nGO\n statement 2")).Return(0);
mocks.ReplayAll();
SimpleAdoTestUtils.ExecuteSqlScript(adoTemplate, scriptResource, false, SimpleAdoTestUtils.BLOCKDELIM_SEMICOLON_EXP);
mocks.VerifyAll();
}
[Test]
public void ExecuteScriptTransactedSuccess()
{
IDbProvider dbProvider = (IDbProvider) mocks.DynamicMock(typeof(IDbProvider));
IDbConnection dbConnection = (IDbConnection) mocks.CreateMock(typeof (IDbConnection));
IDbTransaction dbTx = (IDbTransaction) mocks.CreateMock(typeof (IDbTransaction));
IDbCommand dbCommand = (IDbCommand) mocks.CreateMock(typeof (IDbCommand));
DefaultTransactionDefinition txDefinition = new DefaultTransactionDefinition();
Expect.Call(dbProvider.CreateConnection()).Return(dbConnection);
dbConnection.Open();
Expect.Call(dbConnection.BeginTransaction(txDefinition.TransactionIsolationLevel)).Return(dbTx);
Expect.Call(dbProvider.CreateCommand()).Return(dbCommand);
dbCommand.Connection = dbConnection;
dbCommand.Transaction = dbTx;
dbCommand.CommandText = "simple sql cmd";
dbCommand.CommandType = CommandType.Text;
Expect.Call(dbCommand.ExecuteNonQuery()).Return(0);
dbTx.Commit();
dbCommand.Dispose();
dbConnection.Dispose();
mocks.ReplayAll();
AdoTemplate adoOps = new AdoTemplate(dbProvider);
IPlatformTransaction tx = SimpleAdoTestUtils.CreateTransaction(dbProvider, txDefinition);
SimpleAdoTestUtils.ExecuteSqlScript(adoOps, "simple sql cmd");
tx.Commit();
tx.Dispose();
mocks.VerifyAll();
}
[Test]
public void ExecuteScriptTransactedRollsbackIfNoCommit()
{
IDbProvider dbProvider = (IDbProvider) mocks.CreateMock(typeof(IDbProvider));
IDbConnection dbConnection = (IDbConnection) mocks.CreateMock(typeof (IDbConnection));
IDbTransaction dbTx = (IDbTransaction) mocks.CreateMock(typeof (IDbTransaction));
DefaultTransactionDefinition txDefinition = new DefaultTransactionDefinition();
Expect.Call(dbProvider.CreateConnection()).Return(dbConnection);
dbConnection.Open();
Expect.Call(dbConnection.BeginTransaction(txDefinition.TransactionIsolationLevel)).Return(dbTx);
dbTx.Rollback();
dbConnection.Dispose();
mocks.ReplayAll();
AdoTemplate adoOps = new AdoTemplate(dbProvider);
IPlatformTransaction tx = SimpleAdoTestUtils.CreateTransaction(dbProvider, txDefinition);
tx.Dispose();
mocks.VerifyAll();
}
}
}