diff --git a/src/Faker.NET.Files/Csv/CsvFaker.cs b/src/Faker.NET.Files/Csv/CsvFaker.cs
index 7775a4b..b9713b8 100644
--- a/src/Faker.NET.Files/Csv/CsvFaker.cs
+++ b/src/Faker.NET.Files/Csv/CsvFaker.cs
@@ -1,222 +1,133 @@
-using System.Collections.Concurrent;
+using System;
using Faker.NET.Attributes;
+using Faker.NET.Common.Exceptions;
-namespace Faker.NET.Files.Csv
+namespace Faker.NET.Files.Csv;
+
+public class CsvFaker : IDisposable
{
- public class CsvFaker
+ public static CsvFaker ToFile(string path)
{
- ///
- /// Constructor
- ///
- public CsvFaker()
- {
- BaseStream = new MemoryStream();
- }
-
- ///
- /// Constructor
- ///
- /// Opens stream to write to
- public CsvFaker(string outputFile)
- {
- BaseStream = File.Open(outputFile, new FileStreamOptions
- {
- Mode = FileMode.OpenOrCreate,
- Access = FileAccess.ReadWrite,
- });
- }
-
- ///
- /// Stream that can be written to for output
- ///
- /// The stream (must have write permissions)
- ///
- public CsvFaker(Stream stream)
- {
- if (!stream.CanWrite)
- {
- throw new Exception("Unable to write to stream");
- }
-
- BaseStream = stream;
- }
-
- public Stream BaseStream { get; private set; }
+ ThrowHelper.IfNullOrEmpty(path, $"{nameof(CsvFaker)} file path cannot be null or empty.");
- ///
- /// Change the delimiter to whatever best suits your uses
- ///
- ///
- ///
- public CsvFaker UpdateDelimiter(char delimiter)
+ return new CsvFaker(System.IO.File.Open(path, new FileStreamOptions
{
- _delimiter = delimiter;
- return this;
- }
+ Mode = FileMode.OpenOrCreate,
+ Access = FileAccess.ReadWrite,
+ }));
+ }
- ///
- /// Builder way to add columns and functions to perform based on headers
- ///
- ///
- ///
- ///
- public CsvFaker AddColumn(string columnName, Func func)
- {
+ public static CsvFaker ToStream(Stream stream)
+ {
+ return new CsvFaker(stream);
+ }
- _headers.Add(columnName, func);
- return this;
- }
+ private CsvFaker(Stream stream)
+ {
+ ThrowHelper.IfNotWritable(stream);
+ _stream = new StreamWriter(stream);
+ }
- ///
- /// Adds a column header and the static value that will be put in the rows
- ///
- ///
- ///
- ///
- public CsvFaker AddColumn(string columnName, string value)
- {
- _headers.Add(columnName, () => value);
- return this;
- }
+ ///
+ /// Change the delimiter to whatever best suits your uses
+ ///
+ ///
+ ///
+ public CsvFaker WithDelimiter(char delimiter)
+ {
+ _delimiter = delimiter;
+ return this;
+ }
- ///
- /// Amount of rows to be generated when or are called
- ///
- ///
- public uint GetRowCount()
- {
- return _rowsCountToGenerate;
- }
+ ///
+ /// Generate a csv based on a type. Properties to have data generated must use an attribute that extends
+ ///
+ /// Type to generate csv from
+ ///
+ public CsvFaker FromClass()
+ {
+ var type = typeof(T);
- ///
- /// Generate a csv based on a type. Properties to have data generated must use an attribute that extends
- ///
- /// Type to generate csv from
- ///
- public IEnumerable Generate()
+ foreach (var prop in type.GetProperties())
{
- var type = typeof(T);
+ var attrs = prop.GetCustomAttributes(typeof(FakerAttribute), true) as FakerAttribute[] ??
+ throw new Exception();
- foreach (var prop in type.GetProperties())
+ foreach (var attr in attrs)
{
- var attrs = prop.GetCustomAttributes(typeof(FakerAttribute), true) as FakerAttribute[] ??
- throw new Exception();
-
- foreach (var attr in attrs)
- {
- _headers.Add(prop.Name, () => attr.GetPropertyValue().ToString() ?? string.Empty);
- }
+ _columnMetadata.Add(prop.Name, () => attr.GetPropertyValue().ToString() ?? string.Empty);
}
-
- return Generate();
}
- ///
- /// Defaults to 10 can update to any uint value
- ///
- ///
- ///
- public CsvFaker Iterations(uint count)
- {
- _rowsCountToGenerate = count;
- return this;
- }
+ return this;
+ }
- ///
- /// Generate a single row with no headers
- ///
- ///
- public string GenerateRow()
+ public CsvFaker WithColumns(Dictionary> columns)
+ {
+ foreach (var key in columns.Keys)
{
- var output = new List();
-
- foreach ((var header, var func) in _headers)
- {
- var val = func();
- if (val.Contains(','))
- {
- output.Add($"\"{val}\"");
- }
- else
- {
- output.Add(val);
- }
- }
-
- return JoinColumns(output);
+ _columnMetadata[key] = columns[key];
}
+ return this;
+ }
- ///
- /// Generates the entire csv (headers and rows).
- ///
- ///
- public IEnumerable Generate()
- {
- yield return JoinColumns(_headers.Keys);
-
- var count = 0;
+ public CsvFaker WithRowCount(uint rowCount)
+ {
+ _rowCount = rowCount;
+ return this;
+ }
- while (count++ < _rowsCountToGenerate)
- {
- yield return GenerateRow();
- }
- }
+ public void Write(bool keepStreamOpen = false)
+ {
+ var headers = _columnMetadata.Keys.ToArray();
+ var headerCount = headers.Length - 1;
+ var row = new string[headerCount];
+ WriteRow(headers);
- public string[] GenerateParallel(int batchSize = 1000)
+ for (var i = 0; i < _rowCount; i++)
{
- var arr = new string[_rowsCountToGenerate];
- arr[0] = JoinColumns(_headers.Keys);
-
- Parallel.ForEach(Partitioner.Create(1, arr.Length, batchSize), range =>
+ for (var j = 0; j < headerCount; j++)
{
- for (int i = range.Item1; i < range.Item2; i++)
- {
- arr[i] = GenerateRow();
- }
- });
+ row[j] = _columnMetadata[headers[j]]();
+ }
- return arr;
+ WriteRow(row);
}
- ///
- /// Outputs the data to the .
- /// Writes to a if a file is not given.
- ///
- public void WriteRows()
+ if (keepStreamOpen)
{
- using (var streamWriter = new StreamWriter(BaseStream))
- {
- foreach (var line in Generate())
- {
- streamWriter.WriteLine(line);
- }
- }
+ _stream.Flush();
}
-
- ///
- /// Clears the headers and value creating funcs. Allows to start fresh.
- ///
- ///
- public bool Clear()
+ else
{
- _headers = new();
-
- return _headers.Count == 0;
+ _stream.Close();
}
+ }
- private string JoinColumns(IEnumerable input)
+ public void Dispose()
+ {
+ try
{
- return string.Join(_delimiter, input);
+ _stream.Dispose();
}
-
- ~CsvFaker()
+ finally
{
- BaseStream?.Dispose();
+ GC.SuppressFinalize(this);
}
+ }
- private Dictionary> _headers = new();
- private uint _rowsCountToGenerate = 10;
- private char _delimiter = ',';
+ ~CsvFaker()
+ {
+ _stream?.Dispose();
}
-}
+ private void WriteRow(string[] values)
+ {
+ _stream.WriteLine(string.Join(_delimiter, values));
+ }
+
+ private char _delimiter = ',';
+ private uint _rowCount = 500;
+ private readonly StreamWriter _stream;
+ private readonly Dictionary> _columnMetadata = new Dictionary>();
+}
diff --git a/src/Faker.NET/Attributes/FakerPersonAttributes.cs b/src/Faker.NET/Attributes/FakerPersonAttributes.cs
index b2f710e..08deacd 100644
--- a/src/Faker.NET/Attributes/FakerPersonAttributes.cs
+++ b/src/Faker.NET/Attributes/FakerPersonAttributes.cs
@@ -11,13 +11,16 @@ public class FakerPersonBioAttribute : FakerAttribute
public class FakerPersonFirstNameAttribute : FakerAttribute
{
public Sex? Sex { get; set; } = null;
+
public override object GetPropertyValue() => Faker.Person.FirstName(Sex);
}
public class FakerPersonFullNameAttribute : FakerAttribute
{
public string? FirstName { get; set; } = null;
+
public string? LastName { get; set; } = null;
+
public Sex? Sex { get; set; } = null;
public override object GetPropertyValue() => Faker.Person.FullName(FirstName, LastName, Sex);
@@ -50,18 +53,21 @@ public class FakerPersonJobTypeAttribute : FakerAttribute
public class FakerPersonLastNameAttribute : FakerAttribute
{
public Sex? Sex { get; set; } = null;
+
public override object GetPropertyValue() => Faker.Person.LastName(Sex);
}
public class FakerPersonMiddleNameAttribute : FakerAttribute
{
public Sex? Sex { get; set; } = null;
+
public override object GetPropertyValue() => Faker.Person.MiddleName(Sex);
}
public class FakerPersonPrefixAttribute : FakerAttribute
{
public Sex? Sex { get; set; } = null;
+
public override object GetPropertyValue() => Faker.Person.Prefix(Sex);
}
diff --git a/src/Faker.NET/Common/Exceptions/ThrowHelper.cs b/src/Faker.NET/Common/Exceptions/ThrowHelper.cs
index 64e3009..952aacf 100644
--- a/src/Faker.NET/Common/Exceptions/ThrowHelper.cs
+++ b/src/Faker.NET/Common/Exceptions/ThrowHelper.cs
@@ -2,6 +2,22 @@ namespace Faker.NET.Common.Exceptions;
public static class ThrowHelper
{
+ public static void IfNullOrEmpty(string value, string message)
+ {
+ if (string.IsNullOrEmpty(value))
+ {
+ throw new NullReferenceException(message);
+ }
+ }
+
+ public static void IfNotWritable(Stream stream, string message = "Unable to write to stream")
+ {
+ if (!stream.CanWrite)
+ {
+ throw new Exception(message);
+ }
+ }
+
public static void NotImplementedException()
{
throw new NotImplementedException();
diff --git a/tests/Faker.NET.Tests/Attributes/Computer.cs b/tests/Faker.NET.Tests/Attributes/Computer.cs
index 48cc73f..3bba66d 100644
--- a/tests/Faker.NET.Tests/Attributes/Computer.cs
+++ b/tests/Faker.NET.Tests/Attributes/Computer.cs
@@ -8,25 +8,16 @@ public class Computer : DeterministicTestClass
public void ClassAttributesCsv()
{
string[] expected = {
- "DisplayName,DomainName,DomainSuffix,DomainWord,Email,Emoji,HttpMethod,HttpStatusCode,IPv4,IPv6,JWT,Mac,Password,Port,Protocol,Url,UserAgent,Username",
-"johanj,ripe-boring.toys,.limited,shadowy-precious,zvolkman@uniform-burly.okinawa,🪝,DELETE,504 Gateway Timeout,139.99.188.167,d661:ab44:dc89:ed19:a4b1:77f9:32fd:b90f,,6B9D8C6F97E7,2aatY!E0>8jT8a&,9821,http,https://bustling-dull.lawyer,\"Mozilla/5.0 (Linux; Android 12; SM-G973F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36\",jschmeler",
-"rbarrows,neat-happy-go-lucky.am,.fish,enchanting-powerless,madelynnh@flimsy-easy.dentist,🔝,GET,300 Multiple Choices,214.73.235.20,d083:4092:acc3:1e02:fd9e:2e1d:c6d3:c119,,F8C1F202EAE6,67/#54;7?1rH9l3,44138,http,https://concerned-true.moe,\"Mozilla/5.0 (Linux; Android 13; SM-G991U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36\",halle.tremblay",
-"theron.turner,jagged-broken.consulting,.cooking,red-wasteful,blick.obie@forsaken-energetic.stream,👨🍳,POST,404 Not Found,243.73.124.209,c924:e90f:23be:d5eb:6ba3:3cc7:e3ae:f0da,,BB85A841CB8C,#P4818>37H42$r2,44880,https,https://lighthearted-first.lighting,\"Mozilla/5.0 (iPhone13,2; U; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/15E148 Safari/602.1\",letitia.rohan",
-"devanted,right-scaly.media,.supplies,excited-vengeful,dach.dimitri@confused-unhealthy.lease,🐅,GET,413 Content Too Large,129.227.72.105,d0b:4fba:a3d3:a40f:7416:3033:a2a9:ef0,,0C6376B7E241,g2)Re4bByyy8\"0i,11298,http,https://intent-bare.la,\"Mozilla/5.0 (Linux; Android 12; 2201116SG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36\",drake.cruickshank",
-"greggz,colorful-ideal.us.com,.pet,huge-vivacious,aemmerich@excellent-stained.hosting,👨🏿🎤,PUT,422 Unprocessable Content (WebDAV),252.190.28.12,4e82:7d:b18:ac83:19f4:c658:ebd4:876d,,F3F105B0FEDD,32#80CLBD8b88fS,27620,https,https://buttery-ajar.reviews,\"Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36\",ostanton",
+"DisplayName,DomainName,DomainSuffix,DomainWord,Email,Emoji,HttpMethod,HttpStatusCode,IPv4,IPv6,JWT,Mac,Password,Port,Protocol,Url,UserAgent,Username",
+"johanj,ripe-boring.toys,.limited,shadowy-precious,zvolkman@uniform-burly.okinawa,🪝,DELETE,504 Gateway Timeout,139.99.188.167,d661:ab44:dc89:ed19:a4b1:77f9:32fd:b90f,,6B9D8C6F97E7,2aatY!E0>8jT8a&,9821,http,https://bustling-dull.lawyer,Mozilla/5.0 (Linux; Android 12; SM-G973F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36",
+"jschmeler,super-well-lit.gs,.asia,oddball-neat,ffarrell@quarterly-winding.dance,🪰,POST,226 IM Used (HTTP Delta encoding),70.229.54.14,5932:73cb:ead0:8340:92ac:c31e:2fd:9e2e,,35C05F8C1F20,x37H,65166,https,https://soft-elliptical.qpon,Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1",
+"cgoodwin,quarrelsome-lighthearted.dental,.lighting,avaricious-plump,dicki.philip@sure-footed-married.coach,📏,DELETE,415 Unsupported Media Type,217.62.236.67,7052:b385:e719:afec:da9b:f51b:faa:640d,,ED12B2BB40E6,Ca3lSWheYNH!s$l,3446,http,https://wise-celebrated.xyz,Mozilla/5.0 (iPhone14,6; U; CPU iPhone OS 15_4 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/19E241 Safari/602.1",
+"wilmer.labadie,well-groomed-actual.claims,.family,decisive-affectionate,kirlin.hester@short-idolized.click,🥳,GET,502 Bad Gateway,253.216.31.97,2317:e8ea:a6fd:4e70:eca2:aef4:b368:40ae,,FB1080C59FD9,555m21h\"8732#80,22545,http,https://lavish-juicy.diet,Mozilla/5.0 (iPhone12,1; U; CPU iPhone OS 13_0 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/15E148 Safari/602.1"
};
- var csvFaker = CsvUtils.ToCsvRows();
-
- Assert.That(csvFaker.Count, Is.EqualTo(expected.Length));
-
- Assert.Multiple(() =>
- {
- for (int i = 0; i < csvFaker.Count; i++)
- {
- Asserts.IsEqual(csvFaker[i], expected[i]);
- }
- });
+ var csvFaker = CsvUtils.ToCsvRows().ToArray();
+ Assert.That(csvFaker.ToArray(), Is.EquivalentTo(expected));
}
}
diff --git a/tests/Faker.NET.Tests/Attributes/Lorem.cs b/tests/Faker.NET.Tests/Attributes/Lorem.cs
index 5c55542..f77aa48 100644
--- a/tests/Faker.NET.Tests/Attributes/Lorem.cs
+++ b/tests/Faker.NET.Tests/Attributes/Lorem.cs
@@ -9,17 +9,17 @@ public class Lorem : DeterministicTestClass
public void ClassAttributesCsv()
{
var csvFaker = CsvUtils.ToCsvRows();
-
- Assert.That(csvFaker.Count, Is.EqualTo(6));
+ var count = 0;
Assert.Multiple(() =>
{
- for (int i = 0; i < csvFaker.Count; i++)
+ foreach (var line in csvFaker)
{
- var line = csvFaker[i].Replace(",", string.Empty);
- Assert.That(line, Is.Not.WhiteSpace.Or.Null.Or.Empty);
+ count++;
+ Assert.That(line.Replace(",", string.Empty), Is.Not.WhiteSpace.Or.Null.Or.Empty);
}
});
+ Assert.That(count, Is.EqualTo(6));
}
}
diff --git a/tests/Faker.NET.Tests/Attributes/PhoneNumbers.cs b/tests/Faker.NET.Tests/Attributes/PhoneNumbers.cs
index e5f6dbc..49a7cb0 100644
--- a/tests/Faker.NET.Tests/Attributes/PhoneNumbers.cs
+++ b/tests/Faker.NET.Tests/Attributes/PhoneNumbers.cs
@@ -11,25 +11,15 @@ public void ClassAttributesCsv()
{
string[] expected = {
"PhoneNumber,CountryCode,WithAreaCode",
- "253-860-8565 x8848,805-776-8436 x5711,885.314.1177 x5336",
- "(747) 485-4746 x2001,273-860-2160,878.234.7781 x0611",
- "1-114-741-8757 x840,(530) 325-5823 x7212,1-202-728-0584 x50023",
- "1-162-360-3846 x181,286-836-6565,607.655.6787 x488",
- "1-262-347-1473,1-317-563-0580 x8428,1-401-268-6610",
+ "253-860-8565 x8848,805-776-8436 x5711",
+ "885.314.1177 x5336,(747) 485-4746 x2001",
+ "273-860-2160,878.234.7781 x0611",
+ "1-114-741-8757 x840,(530) 325-5823 x7212",
+ "1-202-728-0584 x50023,1-162-360-3846 x181"
};
- var csvFaker = CsvUtils.ToCsvRows();
-
- Assert.That(csvFaker.Count, Is.EqualTo(expected.Length));
-
- Assert.Multiple(() =>
- {
- for (int i = 0; i < csvFaker.Count; i++)
- {
- Console.WriteLine(csvFaker[i]);
- Assert.That(csvFaker[i], Is.EqualTo(expected[i]));
- }
- });
+ var csvFaker = CsvUtils.ToCsvRows().ToArray();
+ Assert.That(csvFaker, Is.EquivalentTo(expected));
}
}
diff --git a/tests/Faker.NET.Tests/Files/Csv.cs b/tests/Faker.NET.Tests/Files/Csv.cs
index af1f159..a5e1f95 100644
--- a/tests/Faker.NET.Tests/Files/Csv.cs
+++ b/tests/Faker.NET.Tests/Files/Csv.cs
@@ -1,189 +1,83 @@
using Faker.NET.Attributes;
using Faker.NET.Files.Csv;
+using Faker.NET.Tests.Utils;
namespace Faker.NET.Tests.Files
{
- public class Csv
+ public class Csv : FileBasedTestClass
{
- [Test]
- public void GenerateCsv()
- {
- // using the static first name here will generate the same same for every row
- // use () => Name.FirstName to turn this into a func.
- var faker = CreateCsvFaker();
-
- // Generate a single row
- var value = faker.GenerateRow();
-
- // default 10 rows
- var values = faker.Generate();
-
- // 10 rows and 1 header row
- Assert.That(values.Count(), Is.EqualTo(11));
-
- values = faker.Iterations(25).Generate();
-
- // 25 rows and 1 header row
- Assert.That(values.Count(), Is.EqualTo(26));
- }
-
[Test]
[TestCase(100_000)]
[TestCase(200_000)]
[TestCase(500_000)]
+ [TestCase(1_000_000)]
public void GenerateMassiveRows(int rowCount)
{
// more of a proof of concept rather than testing because Generate() returns an IEnumerable
// at time of writing will generate 3,000,000 values in about 2.5 seconds
- var faker = CreateCsvFaker().Iterations((uint)rowCount);
- faker.Generate().ToArray();
- }
-
- [Test]
- [TestCase(100_000)]
- [TestCase(200_000)]
- [TestCase(500_000)]
- public void GenerateParallelMassiveRows(int rowCount)
- {
- var faker = CreateCsvFaker().Iterations((uint)rowCount);
- faker.GenerateParallel();
+ var path = IO.GetRandomTempFilePath();
+ var faker = CsvFaker.ToFile(path)
+ .AddTestColumns()
+ .WithRowCount((uint)rowCount);
+ faker.Write();
}
[Test]
public void GenerateFileFromPath()
{
- var tempPath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
-
- var faker = CreateCsvFaker(tempPath);
- faker.WriteRows();
-
- ICollection lines = new List();
-
- using (var file = File.OpenRead(tempPath))
- using (var reader = new StreamReader(file))
- {
- while (!reader.EndOfStream)
- {
- var line = reader.ReadLine();
- if (line is not null)
- {
- lines.Add(line);
- }
- }
- }
-
- Assert.That(lines.Count, Is.EqualTo(11));
-
- File.Delete(tempPath);
+ var tempPath = IO.GetRandomTempFilePath();
+ var faker = CsvFaker.ToFile(tempPath).AddTestColumns();
+ faker.Write();
+ CheckFile(tempPath, 501);
}
[Test]
public void GenerateFileFromStreamReadError()
{
- var tempPath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+ var tempPath = IO.GetRandomTempFilePath();
- using (var stream = File.OpenRead(tempPath))
- {
- Assert.Throws(() => CreateCsvFaker(stream));
- }
-
- if (File.Exists(tempPath))
- {
- File.Delete(tempPath);
- }
+ using var stream = File.Open(tempPath, FileMode.OpenOrCreate, FileAccess.Read);
+ Assert.Throws(() => CsvFaker.ToStream(stream));
}
[Test]
public void GenerateFileFromStream()
{
- var tempPath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+ var tempPath = IO.GetRandomTempFilePath();
using var writeStream = File.OpenWrite(tempPath);
-
- var faker = CreateCsvFaker(writeStream);
-
- faker.WriteRows();
-
- ICollection lines = new List();
-
- using (var file = File.OpenRead(tempPath))
- using (var reader = new StreamReader(file))
- {
- while (!reader.EndOfStream)
- {
- lines.Add(reader.ReadLine() ?? string.Empty);
- }
- }
-
- Assert.That(lines.Count, Is.EqualTo(11));
-
- File.Delete(tempPath);
- }
-
- [Test]
- [TestCase(100_000)]
- public void GenerateFile(int rowCount)
- {
- var tempPath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
- var lines = CreateFileGetLineCount(tempPath, (uint)rowCount);
-
- // amount of lines plus the header
- Assert.That(lines, Is.EqualTo(rowCount + 1));
+ var faker = CsvFaker.ToStream(writeStream).AddTestColumns();
+ faker.Write();
+ CheckFile(tempPath, 501);
}
[Test]
public void GenerateTypeCsv()
{
- var csvFaker = new CsvFaker()
- .Iterations(100)
- .Generate();
+ var path = IO.GetRandomTempFilePath();
+ CsvFaker.ToFile(path)
+ .WithRowCount(100)
+ .FromClass()
+ .Write();
- foreach (var line in csvFaker)
- {
- // make sure there is actually data there
- var lines = line.Split(',', StringSplitOptions.RemoveEmptyEntries);
- Assert.That(lines.Length, Is.GreaterThanOrEqualTo(3));
- }
-
- Assert.That(csvFaker.Count(), Is.EqualTo(101));
+ CheckFile(path, 101);
}
- private int CreateFileGetLineCount(string tempPath, uint rowCount = 10)
+ private static void CheckFile(string path, uint expectedRows)
{
- using var stream = File.OpenWrite(tempPath);
-
- var faker = CreateCsvFaker(stream).Iterations(rowCount);
- faker.WriteRows();
-
- var lines = 0;
-
- using (var file = File.OpenRead(tempPath))
+ var actualLines = 0;
+ using (var file = File.OpenRead(path))
using (var reader = new StreamReader(file))
{
while (!reader.EndOfStream)
{
- reader.ReadLine();
- lines++;
+ if (reader.ReadLine() is not null)
+ {
+ actualLines += 1;
+ }
}
}
- File.Delete(tempPath);
-
- return lines;
- }
-
- private CsvFaker CreateCsvFaker()
- {
- return new CsvFaker().AddTestColumns();
- }
-
- private CsvFaker CreateCsvFaker(string tempPath)
- {
- return new CsvFaker(tempPath).AddTestColumns();
- }
-
- private CsvFaker CreateCsvFaker(Stream stream)
- {
- return new CsvFaker(stream).AddTestColumns();
+ Assert.That(expectedRows, Is.EqualTo(actualLines));
}
public class FakeClass
@@ -202,17 +96,3 @@ public class FakeClass
}
}
}
-
-internal static class CsvFakerExtensions
-{
- public static CsvFaker AddTestColumns(this CsvFaker faker)
- {
- return faker
- .AddColumn("name", () => Faker.NET.Faker.Person.FirstName())
- .AddColumn("date", () => Faker.NET.Faker.Date.Anytime().ToString())
- .AddColumn("update_date", () => DateTime.Now.ToString("dddd, dd MMMM yyyy HH:mm:ss"))
- .AddColumn("text", () => Faker.NET.Faker.Lorem.Words(35, 35))
- .AddColumn("ip", () => Faker.NET.Faker.Internet.IPv4())
- .AddColumn("small_variable_message", () => Faker.NET.Faker.Lorem.Words(5, 10));
- }
-}
diff --git a/tests/Faker.NET.Tests/Files/Sql.cs b/tests/Faker.NET.Tests/Files/Sql.cs
index d5f4073..e7e560f 100644
--- a/tests/Faker.NET.Tests/Files/Sql.cs
+++ b/tests/Faker.NET.Tests/Files/Sql.cs
@@ -1,14 +1,15 @@
using Faker.NET.Files.Sql;
+using Faker.NET.Tests.Utils;
using System.Data;
namespace Faker.NET.Tests.Files
{
- internal class Sql
+ internal class Sql : FileBasedTestClass
{
[Test]
public void GenerateInsert()
{
- var tempPath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+ var tempPath = IO.GetRandomTempFilePath();
using var writeStream = File.OpenWrite(tempPath);
var faker = new SqlFaker(writeStream)
diff --git a/tests/Faker.NET.Tests/Utils/CsvUtils.cs b/tests/Faker.NET.Tests/Utils/CsvUtils.cs
index e005a0f..c301393 100644
--- a/tests/Faker.NET.Tests/Utils/CsvUtils.cs
+++ b/tests/Faker.NET.Tests/Utils/CsvUtils.cs
@@ -4,11 +4,36 @@ namespace Faker.NET.Tests.Utils;
public static class CsvUtils
{
- public static List ToCsvRows()
+ public static IEnumerable ToCsvRows()
{
- return new CsvFaker()
- .Iterations(5)
- .Generate()
- .ToList();
+ using var memStream = new MemoryStream();
+ var faker = CsvFaker.ToStream(memStream)
+ .WithRowCount(5)
+ .FromClass();
+ faker.Write(keepStreamOpen: true);
+
+ memStream.Position = 0;
+ using var streamReader = new StreamReader(memStream);
+ while (!streamReader.EndOfStream)
+ {
+ var line = streamReader.ReadLine();
+ if (line is not null)
+ {
+ yield return line;
+ }
+ }
+ }
+
+ public static CsvFaker AddTestColumns(this CsvFaker faker)
+ {
+ return faker.WithColumns(new()
+ {
+ { "name", () => Faker.Person.FirstName() },
+ { "date", () => Faker.Date.Anytime().ToString() },
+ { "update_date", () => DateTime.Now.ToString("dddd, dd MMMM yyyy HH:mm:ss") },
+ { "text", () => Faker.Lorem.Words(35, 35) },
+ { "ip", () => Faker.Internet.IPv4() },
+ { "small_variable_message", () => Faker.Lorem.Words(5, 10) }
+ });
}
}
diff --git a/tests/Faker.NET.Tests/Utils/FileBasedTestClass.cs b/tests/Faker.NET.Tests/Utils/FileBasedTestClass.cs
new file mode 100644
index 0000000..51a52d4
--- /dev/null
+++ b/tests/Faker.NET.Tests/Utils/FileBasedTestClass.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Faker.NET.Tests.Utils;
+
+public abstract class FileBasedTestClass
+{
+ [TearDown]
+ public void CleanUp()
+ {
+ IO.CleanTempDirectory();
+ }
+}
diff --git a/tests/Faker.NET.Tests/Utils/IO.cs b/tests/Faker.NET.Tests/Utils/IO.cs
new file mode 100644
index 0000000..bc7078b
--- /dev/null
+++ b/tests/Faker.NET.Tests/Utils/IO.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace Faker.NET.Tests.Utils;
+
+public static class IO
+{
+ public static string GetRandomTempFilePath()
+ {
+ return Path.Combine(Path.GetTempPath(), $"fakernet_{Path.GetRandomFileName()}");
+ }
+
+ public static void CleanTempDirectory()
+ {
+ foreach (var file in Directory.GetFiles(Path.GetTempPath(), "fakernet_*"))
+ {
+ File.Delete(file);
+ }
+ }
+}