Skip to content

Commit

Permalink
Merge pull request #8 from Fabian918/feature/makePropertiesSelectable
Browse files Browse the repository at this point in the history
Feature/make properties selectable
  • Loading branch information
Fabian918 committed Jan 19, 2024
2 parents 47b2467 + af9d7bd commit b0fbdc0
Show file tree
Hide file tree
Showing 6 changed files with 324 additions and 100 deletions.
130 changes: 130 additions & 0 deletions CsvPortable/CsvPortable.Tests/PropertySelectionTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
namespace CsvPortable.Tests;

using System.Globalization;
using Attributes;
using Configuration;
using Interfaces;

public class PropertySelectionTest
{
[Theory]
[InlineData(null)]
[InlineData(PropertyMode.Explicit)]
[InlineData(PropertyMode.All)]
public void PropertySelectionModeInParameter(PropertyMode? mode)
{
void AssertParameter(CsvParameter parameter, PropertyMode? expectedMode)
{
Assert.Equal(expectedMode, parameter.PropertyMode);
}

AssertParameter(new CsvParameter(propertyMode: mode), mode ?? CsvParameter.DefaultPropertyMode);
}


[Theory]
[InlineData(PropertyMode.All)]
[InlineData(PropertyMode.Explicit)]
public void ImportExportDataPropertyMode(PropertyMode mode)
{
var objectToExport = new PropertySelectionSpecifiedTestDto()
{
Property1 = 100,
Property2 = "SomethingElse",
Property3 = true,
Property4 = DateTime.Parse("1999.12.12")
};

CsvParameter parameter = new CsvParameter(propertyMode: mode);


void AssertExportedString(string definition, string expectedString, bool shouldBeContained = true)
{
if (shouldBeContained)
{
Assert.Contains(expectedString, definition);
}
else
{
Assert.DoesNotContain(expectedString, definition);
}
}

// Assert Definition.
// Property1 and Property3 should be always in the definition.
// Property2 and Property4 should be in the definition only if mode is All.

AssertExportedString(
ICsvPortable.ExportDefinition<PropertySelectionSpecifiedTestDto>(parameter),
nameof(PropertySelectionSpecifiedTestDto.Property1));


AssertExportedString(
ICsvPortable.ExportDefinition<PropertySelectionSpecifiedTestDto>(parameter),
nameof(PropertySelectionSpecifiedTestDto.Property2),
mode == PropertyMode.All);

AssertExportedString(
ICsvPortable.ExportDefinition<PropertySelectionSpecifiedTestDto>(parameter),
nameof(PropertySelectionSpecifiedTestDto.Property3));

AssertExportedString(
ICsvPortable.ExportDefinition<PropertySelectionSpecifiedTestDto>(parameter),
nameof(PropertySelectionSpecifiedTestDto.Property4),
mode == PropertyMode.All);

// Assert Exported csv string.
// Property1 and Property3 values should be always exported.
// Property2 and Property4 should be exported only if mode is All.

AssertExportedString(
ICsvPortable.ExportToCsvLine(objectToExport, parameter),
objectToExport.Property1.ToString());


AssertExportedString(
ICsvPortable.ExportToCsvLine(objectToExport, parameter),
objectToExport.Property2,
mode == PropertyMode.All);

AssertExportedString(
ICsvPortable.ExportToCsvLine(objectToExport, parameter),
objectToExport.Property3.ToString());

AssertExportedString(
ICsvPortable.ExportToCsvLine(objectToExport, parameter),
objectToExport.Property4.ToString(CultureInfo.CurrentCulture),
mode == PropertyMode.All);

// Assert imported values
// Property1 and Property3 values should be always be imported again.
// Property2 and Property4 should be imported only if mode is All, if not the values should be the defaults.
Assert.Equal(objectToExport.Property1, ICsvPortable.FromCsvRow<PropertySelectionSpecifiedTestDto>(
ICsvPortable.ExportToCsvLine(objectToExport, parameter), parameter).Property1);

Assert.Equal(mode == PropertyMode.All ? objectToExport.Property2 : PropertySelectionSpecifiedTestDto.DefaultProperty2, ICsvPortable.FromCsvRow<PropertySelectionSpecifiedTestDto>(
ICsvPortable.ExportToCsvLine(objectToExport, parameter), parameter).Property2);

Assert.Equal(objectToExport.Property3, ICsvPortable.FromCsvRow<PropertySelectionSpecifiedTestDto>(
ICsvPortable.ExportToCsvLine(objectToExport, parameter), parameter).Property3);

Assert.Equal(mode == PropertyMode.All ? objectToExport.Property4 : PropertySelectionSpecifiedTestDto.DefaultProperty4, ICsvPortable.FromCsvRow<PropertySelectionSpecifiedTestDto>(
ICsvPortable.ExportToCsvLine(objectToExport, parameter), parameter).Property4);
}

public record PropertySelectionSpecifiedTestDto
{
public const int DefaultProperty1 = -1;
public const string DefaultProperty2 = "default";
public const bool DefaultProperty3 = true;
public static readonly DateTime DefaultProperty4 = DateTime.Parse("2022.01.01");

[CsvProperty] public int Property1 { get; set; } = DefaultProperty1;

public string Property2 { get; set; } = DefaultProperty2;

[CsvProperty] public bool Property3 { get; set; } = DefaultProperty3;

public DateTime Property4 { get; set; } = DefaultProperty4;
}
}
155 changes: 71 additions & 84 deletions CsvPortable/CsvPortable/Configuration/CsvParameter.cs
Original file line number Diff line number Diff line change
@@ -1,89 +1,76 @@

using CsvPortable.Interfaces;

namespace CsvPortable.Configuration
{
public class CsvParameter
{
public static CsvParameter Default {get => (null, ";");}
public CsvParameter(CsvConfiguration? configuration)
{
Configuration = configuration;
}

public CsvParameter(CsvConfiguration? configuration, CsvDelimiter delimiter) : this(configuration)
{
Delimiter = delimiter ?? throw new ArgumentNullException(nameof(delimiter));
}

public CsvParameter(CsvConfiguration? configuration, CsvDelimiter delimiter, bool closeEnd) : this(configuration, delimiter)
{
CloseEnd = closeEnd;
}

public CsvParameter(CsvConfiguration? configuration, CsvDelimiter delimiter, bool closeEnd, List<(Type, CsvConfiguration)> specifiedConfigurations) : this(configuration, delimiter, closeEnd)
{
SpecifiedConfigurations = specifiedConfigurations ?? throw new ArgumentNullException(nameof(specifiedConfigurations));
}

public CsvParameter(CsvConfiguration? configuration, CsvDelimiter delimiter, bool closeEnd, params (Type, CsvConfiguration)[] specifiedConfigurations) : this(configuration, delimiter, closeEnd)
{
SpecifiedConfigurations = specifiedConfigurations.ToList();
}



/// <summary>
/// Gets or Sets Configuration for the Type.
/// </summary>
public CsvConfiguration? Configuration { get; set; } = null;

/// <summary>
/// Gets or Sets Delimiter --> default ";"
/// </summary>
public CsvDelimiter Delimiter { get; set; } = ";";

/// <summary>
/// Gets or Sets CloseEnd (The CSVLine gets closed(\r\n)) --> default "true"
/// </summary>
public bool CloseEnd { get; set; } = true;


public CsvParameter ParameterToUse(Type type, bool closeEnd)
{
bool MatchType((Type Type, CsvConfiguration Configuration) t)
{
return t.Type == type;
}

var configToUse = this.SpecifiedConfigurations.Exists(MatchType)
? this.SpecifiedConfigurations.FirstOrDefault(MatchType).Configuration
: this.Configuration;

return new CsvParameter(configToUse, this.Delimiter, closeEnd, this.SpecifiedConfigurations);
}
/// <summary>
/// Gets or Sets Specified Configurations.
/// For Class X use that Specification.
/// </summary>
public List<(Type Type, CsvConfiguration Configuration)> SpecifiedConfigurations { get; set; } = new List<(Type Type, CsvConfiguration Configuration)>();

public static implicit operator CsvParameter((CsvConfiguration? Configuration, CsvDelimiter Delimiter) tupel)
{
return new CsvParameter(tupel.Configuration, tupel.Delimiter);
}

public static implicit operator CsvParameter((CsvConfiguration? Configuration, CsvDelimiter Delimiter, bool CloseEnd) tupel)
{
return new CsvParameter(tupel.Configuration, tupel.Delimiter, tupel.CloseEnd);
}

public static implicit operator CsvParameter((CsvConfiguration Configuration, CsvDelimiter Delimiter, bool CloseEnd, List<(Type, CsvConfiguration)> SpecifiedConfigurations) tupel)
{
return new CsvParameter(tupel.Configuration, tupel.Delimiter, tupel.CloseEnd, tupel.SpecifiedConfigurations);
}



}
public class CsvParameter
{
public static readonly CsvConfiguration? DefaultConfiguration = null;
public static readonly CsvDelimiter DefaultDelimiter = ";";
public static readonly bool DefaultCloseEnd = true;
public static readonly PropertyMode DefaultPropertyMode = PropertyMode.All;
public static readonly List<(Type, CsvConfiguration)> DefaultSpecifiedConfigurations = new List<(Type, CsvConfiguration)>();

public static CsvParameter Default
{
get => (DefaultConfiguration, DefaultDelimiter);
}

public CsvParameter(CsvConfiguration? configuration = null, CsvDelimiter? delimiter = null, bool? closeEnd = null, PropertyMode? propertyMode = null, List<(Type Type, CsvConfiguration Configuration)>? specifiedConfigurations = null)
{
this.Configuration = configuration ?? DefaultConfiguration;
this.Delimiter = delimiter ?? DefaultDelimiter;
this.CloseEnd = closeEnd ?? DefaultCloseEnd;
this.PropertyMode = propertyMode ?? DefaultPropertyMode;
this.SpecifiedConfigurations = specifiedConfigurations ?? DefaultSpecifiedConfigurations;
}


/// <summary>
/// Gets or Sets Configuration for the Type.
/// </summary>
public CsvConfiguration? Configuration { get; set; }

/// <summary>
/// Gets or Sets Delimiter --> default ";"
/// </summary>
public CsvDelimiter Delimiter { get; set; }

/// <summary>
/// Gets or Sets CloseEnd (The CSVLine gets closed(\r\n)) --> default "true"
/// </summary>
public bool CloseEnd { get; set; }

public PropertyMode PropertyMode { get; set; }


public CsvParameter ParameterToUse(Type type, bool closeEnd)
{
bool MatchType((Type Type, CsvConfiguration Configuration) t)
{
return t.Type == type;
}

var configToUse = this.SpecifiedConfigurations.Exists(MatchType)
? this.SpecifiedConfigurations.FirstOrDefault(MatchType).Configuration
: this.Configuration;

return new CsvParameter(configToUse, this.Delimiter, closeEnd, this.PropertyMode, this.SpecifiedConfigurations);
}

/// <summary>
/// Gets or Sets Specified Configurations.
/// For Class X use that Specification.
/// </summary>
public List<(Type Type, CsvConfiguration Configuration)> SpecifiedConfigurations { get; set; }

public static implicit operator CsvParameter((CsvConfiguration? Configuration, CsvDelimiter Delimiter) tupel)
{
return new CsvParameter(tupel.Configuration, tupel.Delimiter);
}

public static implicit operator CsvParameter((CsvConfiguration? Configuration, CsvDelimiter Delimiter, bool CloseEnd) tupel)
{
return new CsvParameter(tupel.Configuration, tupel.Delimiter, tupel.CloseEnd);
}
}
}
7 changes: 7 additions & 0 deletions CsvPortable/CsvPortable/Configuration/PropertyMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace CsvPortable.Configuration;

public enum PropertyMode
{
Explicit,
All
}
Loading

0 comments on commit b0fbdc0

Please sign in to comment.