Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using Px.Utils.ModelBuilders;
using Px.Utils.ModelBuilders;
using Px.Utils.Models.Metadata.Enums;
using Px.Utils.PxFile;

namespace ModelBuilderTests.ValueParserUtilitiesTests
namespace Px.Utils.UnitTests.ModelBuilderTests.ValueParserUtilitiesTests
{
[TestClass]
public class StringToDimensionTypeTests
Expand All @@ -24,6 +25,27 @@ public void ContentTest()
Assert.AreEqual(expected, actual);
}

[TestMethod]
public void ContentAliasTest()
{
string input = "Contents";
DimensionType expected = DimensionType.Content;
DimensionType actual = ValueParserUtilities.StringToDimensionType(input);
Assert.AreEqual(expected, actual);
}

[TestMethod]
public void CustomAliasTest()
{
string input = "Ranking";
PxFileConfiguration conf = PxFileConfiguration.Default;
conf.Tokens.VariableTypes.Ordinal = ["Ordinal", "Ranking"];

DimensionType expected = DimensionType.Ordinal;
DimensionType actual = ValueParserUtilities.StringToDimensionType(input, conf);
Assert.AreEqual(expected, actual);
}

[TestMethod]
public void DefaultValueTest()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Px.Utils.Validation;
using Px.Utils.Validation.ContentValidation;
using Px.Utils.Validation.SyntaxValidation;
using Px.Utils.PxFile;
using System.Text;
using System.Reflection;

Expand Down Expand Up @@ -536,6 +537,55 @@ public void ValidateValueTypesCalledWithStructuredEntryArrayWithWrongValuesRetur
}
}

[TestMethod]
public void ValidateValueContentsCalledWithStructuredEntryArrayWithKnownDimensionTypeAliasesReturnsWithWarnings()
{
Comment thread
sakari-malkki marked this conversation as resolved.
// Arrange
ValidationStructuredEntry[] entries = ContentValidationFixtures.STRUCTURED_ENTRY_ARRAY_WITH_KNOWN_DIMENSIONTYPE_ALIASES;
ContentValidator validator = new(filename, encoding, entries);
// Act
foreach (ValidationStructuredEntry entry in entries)
{
ValidationFeedback? result = ContentValidator.ValidateValueContents(
entry,
validator
);
// Assert
Assert.IsNotNull(result);
Assert.HasCount(1, result);
Assert.AreEqual(ValidationFeedbackRule.InvalidValueFound, result.First().Key.Rule);
Assert.AreEqual(ValidationFeedbackLevel.Warning, result.First().Key.Level);
}
}

[TestMethod]
public void ValidateValueContentsCalledWithConfiguredDimensionTypeAliasReturnsWithWarning()
{
// Arrange
PxFileConfiguration conf = PxFileConfiguration.Default;
conf.Tokens.VariableTypes.Ordinal = ["Ordinal", "Ranking"];

ValidationStructuredEntry entry = new(
filename,
new ValidationStructuredEntryKey("VARIABLE-TYPE", "fi", "foo"),
"Ranking",
0,
[],
0,
Px.Utils.Validation.ValueType.StringValue);

ContentValidator validator = new(filename, encoding, [entry], conf: conf);

// Act
ValidationFeedback? result = ContentValidator.ValidateValueContents(entry, validator);

// Assert
Assert.IsNotNull(result);
Assert.HasCount(1, result);
Assert.AreEqual(ValidationFeedbackRule.InvalidValueFound, result.First().Key.Rule);
Assert.AreEqual(ValidationFeedbackLevel.Warning, result.First().Key.Level);
}

[TestMethod]
public void ValidateValueAmountsCalledWithUnmatchingAmountOfElementsReturnsWithError()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@ internal static class ContentValidationFixtures
17,
Utils.Validation.ValueType.StringValue);

private static readonly ValidationStructuredEntryKey dimensionTypeEntryKey =
new ("VARIABLE-TYPE", "fi", "foo");

internal static ValidationStructuredEntry[] MINIMAL_STRUCTURED_ENTRY_ARRAY =>
[
charsetEntry,
Expand Down Expand Up @@ -752,6 +755,12 @@ internal static class ContentValidationFixtures
Utils.Validation.ValueType.StringValue),
];

internal static ValidationStructuredEntry[] STRUCTURED_ENTRY_ARRAY_WITH_KNOWN_DIMENSIONTYPE_ALIASES =>
[
new ValidationStructuredEntry(filename, dimensionTypeEntryKey, "Contents", 0, [], 0, Utils.Validation.ValueType.StringValue),
new ValidationStructuredEntry(filename, dimensionTypeEntryKey, "Region", 1, [], 0, Utils.Validation.ValueType.StringValue),
];

internal static ValidationStructuredEntry StructuredEntryWithUnmatchingAmountOfElements =>
new(filename,
codesBarEntry.Key,
Expand Down
45 changes: 33 additions & 12 deletions Px.Utils/ModelBuilders/ValueParserUtilities.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Px.Utils.Models.Metadata.Enums;
using Px.Utils.Models.Metadata.Enums;
using Px.Utils.Models.Metadata.ExtensionMethods;
using Px.Utils.PxFile;

Expand Down Expand Up @@ -102,6 +102,7 @@ public static string GetTimeValValueRangeString(string input, PxFileConfiguratio
/// <summary>
/// Parses a string into a <see cref="DimensionType"/> enumeration value.
/// This method maps the input string to a <see cref="DimensionType"/> enumeration value based on the provided or default PxFileConfiguration configuration.
/// The first configured token for a dimension type is treated as the primary value and any additional configured tokens are treated as aliases.
/// If the input string does not map to a known <see cref="DimensionType"/>, the method returns <see cref="DimensionType.Unknown"/>.
/// </summary>
/// <param name="input">The string to parse into a <see cref="DimensionType"/> enumeration value.</param>
Expand All @@ -110,20 +111,40 @@ public static string GetTimeValValueRangeString(string input, PxFileConfiguratio
public static DimensionType StringToDimensionType(string input, PxFileConfiguration? conf = null)
{
conf ??= PxFileConfiguration.Default;
Dictionary<string, DimensionType> map = new()
Dictionary<string, DimensionType> map = GetDimensionTypeTokenMap(conf);

string cleanString = input.CleanStringDelimeters(conf.Symbols.Value.StringDelimeter);
if (map.TryGetValue(cleanString, out DimensionType value))
{
{conf.Tokens.VariableTypes.Content, DimensionType.Content},
{conf.Tokens.VariableTypes.Time, DimensionType.Time},
{conf.Tokens.VariableTypes.Ordinal, DimensionType.Ordinal},
{conf.Tokens.VariableTypes.Nominal, DimensionType.Nominal},
{conf.Tokens.VariableTypes.Geographical, DimensionType.Geographical},
{conf.Tokens.VariableTypes.Other, DimensionType.Other},
{conf.Tokens.VariableTypes.Unknown, DimensionType.Unknown}
return value;
}

return DimensionType.Unknown;
}

private static Dictionary<string, DimensionType> GetDimensionTypeTokenMap(PxFileConfiguration conf)
{
Dictionary<string, DimensionType> map = [];
Dictionary<DimensionType, string[]> tokensByType = new()
{
{ DimensionType.Content, conf.Tokens.VariableTypes.Content },
{ DimensionType.Time, conf.Tokens.VariableTypes.Time },
{ DimensionType.Ordinal, conf.Tokens.VariableTypes.Ordinal },
{ DimensionType.Nominal, conf.Tokens.VariableTypes.Nominal },
{ DimensionType.Geographical, conf.Tokens.VariableTypes.Geographical },
{ DimensionType.Other, conf.Tokens.VariableTypes.Other },
Comment thread
sakari-malkki marked this conversation as resolved.
Outdated
{ DimensionType.Unknown, conf.Tokens.VariableTypes.Unknown }
};

string cleanString = input.CleanStringDelimeters(conf.Symbols.Value.StringDelimeter);
if (map.TryGetValue(cleanString, out DimensionType value)) return value;
else return DimensionType.Unknown;
foreach (KeyValuePair<DimensionType, string[]> tokenSet in tokensByType)
{
foreach (string token in tokenSet.Value)
{
map[token] = tokenSet.Key;
Comment thread
sakari-malkki marked this conversation as resolved.
Outdated
}
}

return map;
}
}
}
24 changes: 15 additions & 9 deletions Px.Utils/PxFile/PxFileConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Px.Utils.Models.Metadata.Enums;
using Px.Utils.Models.Metadata.Enums;

namespace Px.Utils.PxFile
{
Expand Down Expand Up @@ -107,25 +107,31 @@ private TimeValue() { }
public static TimeValue DefaultTimeValue => new();
}

/// <summary>
/// Defines accepted tokens for parsing and validating dimension types.
/// The first token in each array is treated as the primary value, while additional tokens are treated as aliases.
/// </summary>
public class VariableTypeTokens
{
private const string CONTENT = "Content";
private const string CONTENTS_ALIAS = "Contents";
private const string TIME = "Time";
private const string ORDINAL = "Ordinal";
private const string NOMINAL = "Nominal";
private const string GEOGRAPHICAL = "Geographical";
private const string REGION_ALIAS = "Region";
private const string OTHER = "Other";
private const string UNKNOWN = "Unknown";
private const string CLASSIFICATORY = "Classificatory";

public string Content { get; set; } = CONTENT;
public string Time { get; set; } = TIME;
public string Ordinal { get; set; } = ORDINAL;
public string Nominal { get; set; } = NOMINAL;
public string Geographical { get; set; } = GEOGRAPHICAL;
public string Other { get; set; } = OTHER;
public string Unknown { get; set; } = UNKNOWN;
public string Classificatory { get; set; } = CLASSIFICATORY;
public string[] Content { get; set; } = [CONTENT, CONTENTS_ALIAS];
public string[] Time { get; set; } = [TIME];
public string[] Ordinal { get; set; } = [ORDINAL];
public string[] Nominal { get; set; } = [NOMINAL];
public string[] Geographical { get; set; } = [GEOGRAPHICAL, REGION_ALIAS];
public string[] Other { get; set; } = [OTHER];
public string[] Unknown { get; set; } = [UNKNOWN];
public string[] Classificatory { get; set; } = [CLASSIFICATORY];
Comment thread
sakari-malkki marked this conversation as resolved.
Outdated

private VariableTypeTokens() { }

Expand Down
Loading
Loading