Created
September 22, 2010 22:54
-
-
Save Restuta/592737 to your computer and use it in GitHub Desktop.
CsvFieldsSaver + Tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using Restuta; | |
using System.Text; | |
namespace Restuta.FieldSavers | |
{ | |
/// <summary> | |
/// Writes provided list of values to CSV file. | |
/// </summary> | |
public class CsvFieldsSaver : IFormFieldsSaver | |
{ | |
private readonly TextWriter fileWriter; | |
private const string Comma = ","; | |
private static readonly string LineBreak = Environment.NewLine; | |
private const string DoubleQuote = @""""; | |
/// <summary> | |
/// Initializes a new instance of the <see cref="CsvFieldsSaver"/> class. | |
/// </summary> | |
/// <param name="fileWriter">The file writer.</param> | |
public CsvFieldsSaver(TextWriter fileWriter) | |
{ | |
fileWriter.ThrowIfNull("fileWriter"); | |
this.fileWriter = fileWriter; | |
} | |
/// <summary> | |
/// Saves form values in CSV format using provided <see cref="TextWriter"/>. | |
/// </summary> | |
/// <param name="values"></param> | |
/// <returns></returns> | |
public void Save(IEnumerable<FormItem> values) | |
{ | |
values.ThrowIfNull("values"); | |
this.Write(values.Select(x => x.DisplayName)); | |
this.fileWriter.Write(LineBreak); | |
this.Write(values.Select(x => x.Value)); | |
} | |
/// <summary> | |
/// Writes the specified items using <see cref="TextWriter"/>. | |
/// </summary> | |
/// <param name="items">The items.</param> | |
private void Write(IEnumerable<string> items) | |
{ | |
List<string> enclosedItems = EncloseItemsAccordingToCsvStandard(items); | |
this.fileWriter.Write(string.Join(",", enclosedItems.ToArray())); | |
} | |
private static List<string> EncloseItemsAccordingToCsvStandard(IEnumerable<string> items) | |
{ | |
List<string> itemsCopy = new List<string>(items.Count()); | |
foreach (var item in items) | |
{ | |
string quotedItem = null; | |
if (item == null) | |
{ | |
itemsCopy.Add(string.Empty); | |
continue; | |
} | |
if (item.Contains(DoubleQuote)) | |
{ | |
quotedItem = QuoteEachDoubleQuote(item); | |
} | |
if (item.Contains(Comma) || item.Contains(LineBreak) || item.Contains(DoubleQuote) | |
|| HasLeadingOrTrailingSpaces(item)) | |
{ | |
string enclosedItem = string.Format("\"{0}\"", quotedItem ?? item); | |
itemsCopy.Add(enclosedItem); | |
} | |
else | |
{ | |
itemsCopy.Add(item); | |
} | |
} | |
return itemsCopy; | |
} | |
private static string QuoteEachDoubleQuote(string item) | |
{ | |
const string TwoDoubleQuotes = "\"\""; | |
return item.Replace(DoubleQuote, TwoDoubleQuotes); | |
} | |
private static bool HasLeadingOrTrailingSpaces(string item) | |
{ | |
return item.Length != item.Trim().Length; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using NUnit.Framework; | |
using Rhino.Mocks; | |
using System.Linq; | |
using Restuta.FieldSavers; | |
// ReSharper disable PublicMembersMustHaveComments | |
// ReSharper disable IdentifierWordIsNotInDictionary | |
namespace Restuta.Tests.FieldSavers | |
{ | |
[TestFixture] | |
public class CsvFieldsSaverFixture | |
{ | |
private TextWriter textWriter; | |
[SetUp] | |
public void SetUp() | |
{ | |
this.textWriter = MockRepository.GenerateMock<TextWriter>(); | |
} | |
[Test] | |
public void Ctor_ShouldNotThrow() | |
{ | |
var csvWriter = new CsvFieldsSaver(this.textWriter); | |
} | |
[Test] | |
public void Ctor_NullPassed_ShouldThrow() | |
{ | |
Assert.Throws<ArgumentNullException>(() => new CsvFieldsSaver(null)); | |
} | |
[Test] | |
public void Save_NullPassed_ShouldThrow() | |
{ | |
Assert.Throws<ArgumentNullException>(() => new CsvFieldsSaver(textWriter).Save(null)); | |
} | |
[Test] | |
public void Save_SeveralItemsPassed_ShouldWriteToWriter() | |
{ | |
//arrange | |
var fileWriter = new FileWriter(new StreamWriter(new MemoryStream())); | |
var csvWriter = new CsvFieldsSaver(fileWriter); | |
List<FormItem> items = this.GetFormItems("item1", "item2"); | |
//act | |
csvWriter.Save(items); | |
//assert | |
MemoryStream memoryStream = (MemoryStream)fileWriter.StreamWriter.BaseStream; | |
memoryStream.Position = 0; | |
string result = this.GetResult(memoryStream); | |
Assert.That(result, Is.EqualTo(@"," + Environment.NewLine + @"item1,item2")); | |
} | |
[Test] | |
public void Save_ItemWithComma_ShouldBeEnclosedWithDoubleQuotedCharacter() | |
{ | |
//arrange | |
var memoryStream = new MemoryStream(); | |
var fileWriter = new FileWriter(new StreamWriter(memoryStream)); | |
var csvWriter = new CsvFieldsSaver(fileWriter); | |
List<FormItem> items = this.GetFormItems("ite,m1", "item2"); | |
//act | |
csvWriter.Save(items); | |
//assert | |
string result = this.GetResult(memoryStream); | |
Assert.That(result, Is.EqualTo(@"," + Environment.NewLine + @"""ite,m1"",item2")); | |
} | |
[Test] | |
public void Save_EmptyItem_ShouldWriteEmpty() | |
{ | |
//arrange | |
var memoryStream = new MemoryStream(); | |
var fileWriter = new FileWriter(new StreamWriter(memoryStream)); | |
var csvWriter = new CsvFieldsSaver(fileWriter); | |
List<FormItem> items = this.GetFormItems("item1", string.Empty); | |
//act | |
csvWriter.Save(items); | |
//assert | |
string result = this.GetResult(memoryStream); | |
Assert.That(result, Is.EqualTo(",\r\nitem1,")); | |
} | |
[Test] | |
public void Save_ItemsWithDoubleQuotes_ShouldBeEnclosedToDoubleQuotesAndQuotedEachDoubleQuote() | |
{ | |
//arrange | |
var memoryStream = new MemoryStream(); | |
var fileWriter = new FileWriter(new StreamWriter(memoryStream)); | |
var csvWriter = new CsvFieldsSaver(fileWriter); | |
List<FormItem> items = this.GetFormItems(@"it""e""m1", "item2"); | |
//act | |
csvWriter.Save(items); | |
//assert | |
string result = this.GetResult(memoryStream); | |
Assert.That(result, Is.EqualTo(@"," + Environment.NewLine + @"""it""""e""""m1"",item2")); | |
} | |
[Test] | |
public void Save_ItemsWithLeadingOrTrailingSpaces_MustBeEnclosedWithDoubleQuotes() | |
{ | |
//arrange | |
var memoryStream = new MemoryStream(); | |
var fileWriter = new FileWriter(new StreamWriter(memoryStream)); | |
var csvWriter = new CsvFieldsSaver(fileWriter); | |
List<FormItem> items = this.GetFormItems(@" item1 ", "item2"); | |
//act | |
csvWriter.Save(items); | |
//assert | |
string result = this.GetResult(memoryStream); | |
Assert.That(result, Is.EqualTo(@"," + Environment.NewLine + @""" item1 "",item2")); | |
} | |
[Test] | |
public void Save_ItemsWithEmbeddedLineBrakes_MustBeEnclosedWithDoubleQuotes() | |
{ | |
//arrange | |
var memoryStream = new MemoryStream(); | |
var fileWriter = new FileWriter(new StreamWriter(memoryStream)); | |
var csvWriter = new CsvFieldsSaver(fileWriter); | |
List<FormItem> items = this.GetFormItems(@"ite" + Environment.NewLine + @"m1", "item2"); | |
//act | |
csvWriter.Save(items); | |
//assert | |
string result = this.GetResult(memoryStream); | |
Assert.That(result, Is.EqualTo(@"," + Environment.NewLine + @"""ite" + Environment.NewLine + @"m1"",item2")); | |
} | |
[Test] | |
public void Save_ShouldWriteItemsWithHeaders() | |
{ | |
//arrange | |
var memoryStream = new MemoryStream(); | |
var fileWriter = new FileWriter(new StreamWriter(memoryStream)); | |
var csvWriter = new CsvFieldsSaver(fileWriter); | |
List<FormItem> items = new List<FormItem> | |
{ | |
new FormItem { Value = "item1", DisplayName = "HeaderItem1"}, | |
new FormItem { Value = "item2", DisplayName = "HeaderItem2"} | |
}; | |
//act | |
csvWriter.Save(items); | |
//assert | |
string result = this.GetResult(memoryStream); | |
Assert.That(result, Is.EqualTo(@"HeaderItem1,HeaderItem2" + Environment.NewLine + @"item1,item2")); | |
} | |
[Test] | |
public void Save_ItemsHasNullDisplayNames_ShouldWriteAsEmptyStrings() | |
{ | |
//arrange | |
var memoryStream = new MemoryStream(); | |
var fileWriter = new FileWriter(new StreamWriter(memoryStream)); | |
var csvWriter = new CsvFieldsSaver(fileWriter); | |
List<FormItem> items = new List<FormItem> | |
{ | |
new FormItem { Value = "item1", DisplayName = null}, | |
new FormItem { Value = "item2", DisplayName = null} | |
}; | |
//act | |
csvWriter.Save(items); | |
//assert | |
string result = this.GetResult(memoryStream); | |
Assert.That(result, Is.EqualTo(@"," + Environment.NewLine + @"item1,item2")); | |
} | |
[Test] | |
public void Save_ItemsWithCommasInDisplayName_ShouldBeQuoted() | |
{ | |
//arrange | |
var memoryStream = new MemoryStream(); | |
var fileWriter = new FileWriter(new StreamWriter(memoryStream)); | |
var csvWriter = new CsvFieldsSaver(fileWriter); | |
List<FormItem> items = new List<FormItem> | |
{ | |
new FormItem { Value = "item1", DisplayName = "Header,Item1"}, | |
new FormItem { Value = "item2", DisplayName = "HeaderItem2"} | |
}; | |
//act | |
csvWriter.Save(items); | |
//assert | |
string result = this.GetResult(memoryStream); | |
Assert.That(result, Is.EqualTo(@"""Header,Item1"",HeaderItem2"+ Environment.NewLine +"item1,item2")); | |
} | |
#region private members | |
private string GetResult(MemoryStream memoryStream) | |
{ | |
string result = null; | |
memoryStream.Position = 0; | |
using (var reader = new StreamReader(memoryStream)) | |
{ | |
result = reader.ReadToEnd(); | |
} | |
return result; | |
} | |
private List<FormItem> GetFormItems(params string[] items) | |
{ | |
var formItems = new List<FormItem>(); | |
formItems.AddRange(items.Select(x => new FormItem {Value = x})); | |
return formItems; | |
} | |
#endregion | |
} | |
} | |
// ReSharper restore PublicMembersMustHaveComments | |
// ReSharper restore IdentifierWordIsNotInDictionary |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment