Skip to content

Commit

Permalink
Add MockTable.FromCsv method
Browse files Browse the repository at this point in the history
  • Loading branch information
dvoituron committed Aug 5, 2018
1 parent ac9cf00 commit 455866b
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 65 deletions.
17 changes: 12 additions & 5 deletions DbMocker.Tests/DbMockTableTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,19 +153,26 @@ public void Mock_MockTable_FromCsv_Test()
{
var conn = new MockDbConnection();

string csv = @" Id Name
1 Scott
2 Bill
3 Anders ";
string csv = @" Id Name Birthdate
1 Scott 1980-02-03
2 Bill 1972-01-12
3 Anders 1965-03-14 ";

var table = MockTable.FromCsv(csv);

Assert.AreEqual("Id", table.Columns[0]);
Assert.AreEqual("Name", table.Columns[1]);

Assert.AreEqual(3, table.Rows.RowsCount());

Assert.AreEqual("Scott", table.Rows[0, 1]);
Assert.AreEqual("3", table.Rows[2, 0]);
Assert.IsInstanceOfType(table.Rows[0, 1], typeof(string));

Assert.AreEqual(3, table.Rows[2, 0]);
Assert.IsInstanceOfType(table.Rows[2, 0], typeof(int));

Assert.AreEqual(new DateTime(1972, 1, 12), table.Rows[1, 2]);
Assert.IsInstanceOfType(table.Rows[1, 2], typeof(DateTime));
}

}
Expand Down
4 changes: 2 additions & 2 deletions DbMocker/DbMocker.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>netcoreapp2.1</TargetFramework>
<AssemblyName>Apps72.Dev.Data.DbMocker</AssemblyName>
<RootNamespace>Apps72.Dev.Data.DbMocker</RootNamespace>
<Version>1.3.0</Version>
<Version>1.4.0</Version>
<PackageId>DbMocker</PackageId>
<Authors>Denis Voituron</Authors>
<Product>DbMocker</Product>
Expand All @@ -18,7 +18,7 @@ conn.Mocks.WhenAny()..ReturnsScalar(14);</Description>
<PackageTags>DbMocker, Mocker, SQLServer, Oracle, Sqlite, EntityFramework, EF, Dapper, UnitTest</PackageTags>
<PackageReleaseNotes>https://github.com/Apps72/DbMocker</PackageReleaseNotes>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<AssemblyVersion>1.3.0.0</AssemblyVersion>
<AssemblyVersion>1.4.0.0</AssemblyVersion>
<PackageProjectUrl>https://github.com/Apps72/DbMocker</PackageProjectUrl>
<RepositoryUrl>https://github.com/Apps72/DbMocker</RepositoryUrl>
</PropertyGroup>
Expand Down
16 changes: 14 additions & 2 deletions DbMocker/Helpers/TypeExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
namespace Apps72.Dev.Data.DbMocker.Helpers
{
/// <summary />
internal class TypeExtension
internal static class TypeExtension
{
/// <summary>
/// Returns True if this object is a simple type.
/// See https://msdn.microsoft.com/en-us/library/system.type.isprimitive.aspx
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static bool IsPrimitive(Type type)
public static bool IsPrimitive(this Type type)
{
return type == typeof(DateTime) || type == typeof(Nullable<DateTime>) ||
type == typeof(Decimal) || type == typeof(Nullable<Decimal>) ||
Expand All @@ -31,5 +31,17 @@ public static bool IsPrimitive(Type type)
type == typeof(Double) || type == typeof(Nullable<Double>) ||
type == typeof(Single) || type == typeof(Nullable<Single>);
}

public static Type BestType(this string text)
{
if (DateTime.TryParse(text, out DateTime _)) return typeof(DateTime);
if (Boolean.TryParse(text, out Boolean _)) return typeof(DateTime);
if (Int32.TryParse(text, out Int32 _)) return typeof(Int32);
if (Int64.TryParse(text, out Int64 _)) return typeof(Int64);
if (Double.TryParse(text, out Double _)) return typeof(Double);
if (Decimal.TryParse(text, out Decimal _)) return typeof(Decimal);
if (Char.TryParse(text, out Char _)) return typeof(Char);
return typeof(string);
}
}
}
2 changes: 1 addition & 1 deletion DbMocker/MockReturns.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public void ReturnsScalar<T>(T returns)
/// <summary />
private MockTable ConvertToMockTable<T>(T returns)
{
if (returns == null || returns is DBNull || TypeExtension.IsPrimitive(typeof(T)))
if (returns == null || returns is DBNull || typeof(T).IsPrimitive())
{
return new MockTable()
{
Expand Down
94 changes: 94 additions & 0 deletions DbMocker/MockTableImport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using Apps72.Dev.Data.DbMocker.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Apps72.Dev.Data.DbMocker
{
public partial class MockTable
{
/// <summary />
public static MockTable FromCsv(string content, string delimiter, CsvImportOptions options)
{
var table = MockTable.Empty();
Type[] types = null;
bool isFirstRow = true; // First row = Column names
bool isFirstDataRow = false; // Second row = First data row
bool mustRemoveEmptyLines = (options & CsvImportOptions.RemoveEmptyLines) == CsvImportOptions.RemoveEmptyLines;
bool mustTrimLines = (options & CsvImportOptions.TrimLines) == CsvImportOptions.TrimLines;

foreach (string row in content.Split(Environment.NewLine))
{
if (mustRemoveEmptyLines && string.IsNullOrEmpty(row))
{

}
else
{
string[] data;

if (mustTrimLines)
data = row.Trim().Split(delimiter);
else
data = row.Split(delimiter);

if (isFirstRow)
table.AddColumns(data);
else
{
if (isFirstDataRow)
types = GetTypesOfFirstDataRow(data);

table.AddRow(ConvertStringToTypes(data, types));
}

isFirstRow = false;
isFirstDataRow = !isFirstDataRow ? true : isFirstDataRow;
}
}

return table;
}

/// <summary />
public static MockTable FromCsv(string content, string delimiter)
{
return FromCsv(content, delimiter, CsvImportOptions.RemoveEmptyLines | CsvImportOptions.TrimLines);
}

/// <summary />
public static MockTable FromCsv(string content)
{
return FromCsv(content, "\t");
}

/// <summary />
private static Type[] GetTypesOfFirstDataRow(string[] values)
{
return values.Select(i => i.BestType()).ToArray();
}

/// <summary />
private static object[] ConvertStringToTypes(string[] values, Type[] types)
{
var result = new List<object>();

for (int i = 0; i < values.Length; i++)
{
if (i < types.Length)
result.Add(Convert.ChangeType(values[i], types[i]));
else
result.Add(values[i]);
}

return result.ToArray();
}
}

public enum CsvImportOptions
{
None = 0,
RemoveEmptyLines = 1,
TrimLines = 2,
}
}
54 changes: 0 additions & 54 deletions DbMocker/MockTableStatic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,59 +35,5 @@ public static MockTable SingleCell(object value)
{
return SingleCell(String.Empty, value);
}

/// <summary />
public static MockTable FromCsv(string content, string delimiter, CsvImportOptions options)
{
var table = MockTable.Empty();
bool isFirstRow = true;
bool mustRemoveEmptyLines = (options & CsvImportOptions.RemoveEmptyLines) == CsvImportOptions.RemoveEmptyLines;
bool mustTrimLines = (options & CsvImportOptions.TrimLines) == CsvImportOptions.TrimLines;

foreach (string row in content.Split(Environment.NewLine))
{
if (mustRemoveEmptyLines && string.IsNullOrEmpty(row))
{

}
else
{
string[] data;

if (mustTrimLines)
data = row.Trim().Split(delimiter);
else
data = row.Split(delimiter);

if (isFirstRow)
table.AddColumns(data);
else
table.AddRow(data);

isFirstRow = false;
}
}

return table;
}

/// <summary />
public static MockTable FromCsv(string content, string delimiter)
{
return FromCsv(content, delimiter, CsvImportOptions.RemoveEmptyLines | CsvImportOptions.TrimLines);
}

/// <summary />
public static MockTable FromCsv(string content)
{
return FromCsv(content, "\t");
}
}

public enum CsvImportOptions
{
None = 0,
RemoveEmptyLines = 1,
TrimLines = 2,
}
}
19 changes: 18 additions & 1 deletion ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,21 @@ conn.Mocks
.ReturnsTable(cmd => cmd.Parameters.Count() > 0 ? 14 : 99);
```

using a **CSV string** with all data.
The first row contains the column names.
The first data row defines types for each columns (like in a Excel importation).

```CSharp
string csv = @" Id Name Birthdate
1 Scott 1980-02-03
2 Bill 1972-01-12
3 Anders 1965-03-14 ";

conn.Mocks
.WhenAny()
.ReturnsTable(MockTable.FromCsv(csv));
```

## ReturnsRow

When a condition occured, a single data row will be return.
Expand Down Expand Up @@ -168,7 +183,9 @@ conn.Mocks

- Add `ReturnsRow(T)` and `ReturnsRow(Func<MockCommand, T>)` methods.

### Version 1.4
- Add `MockTable.FromCsv(string)` method.

## Road map

- To create a MockTable from a CSV, to detect column type from values of first row (like Excel)
- DataSets are not yet implemented.

0 comments on commit 455866b

Please sign in to comment.