Skip to content

Commit

Permalink
補完核心元件的單元測試
Browse files Browse the repository at this point in the history
  • Loading branch information
maxzh1999tw committed Dec 16, 2023
1 parent 811890c commit 8f3a491
Show file tree
Hide file tree
Showing 4 changed files with 367 additions and 4 deletions.
6 changes: 3 additions & 3 deletions Excely.UnitTests/ClassListTableConverterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ public void ConvertFromDataWithCustomSchema_ShouldReturnCorrectList()
// Arrange
var table = new ExcelyTable(new List<IList<object?>>
{
new List<object?> { "數字", "文字", "日期", "Enum" },
new List<object?> { 1, "Text1", DateTime.Parse("2023/1/1"), SampleEnum.Enum1 },
new List<object?> { 2, "Text2", DateTime.Parse("2023/1/2"), SampleEnum.Enum2 },
new List<object?> { "數字", "文字", "日期", "Enum", null },
new List<object?> { 1, "Text1", DateTime.Parse("2023/1/1"), SampleEnum.Enum1, "Ignored" },
new List<object?> { 2, "Text2", DateTime.Parse("2023/1/2"), SampleEnum.Enum2, "Ignored" },
});
var options = new ClassListTableConverterOptions<SimpleClass>
{
Expand Down
237 changes: 237 additions & 0 deletions Excely.UnitTests/DictionaryListTableConverterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
using Excely.TableConverters;
using Excely.UnitTests.Models;

namespace Excely.UnitTests
{
[TestClass]
public class DictionaryListTableConverterTests
{
/// <summary>
/// 基礎轉換測試,最簡單的資料,使用預設邏輯。
/// </summary>
[TestMethod]
public void ConvertFromData_ShouldReturnCorrectList()
{
// Arrange
var table = new ExcelyTable(new List<IList<object?>>
{
new List<object?> { "IntValue", "StrigValue", "DateTimeValue", "EnumValue" },
new List<object?> { 1, "Text1", DateTime.Parse("2023/1/1"), SampleEnum.Enum1 },
new List<object?> { 2, "Text2", DateTime.Parse("2023/1/2"), SampleEnum.Enum2 },
});
var converter = new DictionaryListTableConverter();

// Act
var result = converter.ConvertFrom(table).ToList();

// Assert
Assert.AreEqual(2, result.Count);
for (int i = 0; i < result.Count; i++)
{
Assert.AreEqual(table.Data[i + 1][0], result[i]["IntValue"]);
Assert.AreEqual(table.Data[i + 1][1], result[i]["StrigValue"]);
Assert.AreEqual(table.Data[i + 1][2], result[i]["DateTimeValue"]);
Assert.AreEqual(table.Data[i + 1][3], result[i]["EnumValue"]);
}
}

/// <summary>
/// 基礎轉換測試,有可能為 Null 的資料,使用預設邏輯。
/// </summary>
[TestMethod]
public void ConvertFromNullableData_ShouldReturnCorrectListOfSimpleNullableClass()
{
// Arrange
var table = new ExcelyTable(new List<IList<object?>>
{
new List<object?> { "IntValue", "StrigValue", "DateTimeValue", "EnumValue" },
new List<object?> { null, "Text1", DateTime.Parse("2023/1/1"), SampleEnum.Enum1 },
new List<object?> { 1, null, DateTime.Parse("2023/1/2"), SampleEnum.Enum2 },
new List<object?> { 2, "Text2", null, SampleEnum.Enum3 },
new List<object?> { 3, "Text3", DateTime.Parse("2023/1/3"), null },
});
var converter = new DictionaryListTableConverter();

// Act
var result = converter.ConvertFrom(table).ToList();

// Assert
Assert.AreEqual(4, result.Count);
for (int i = 0; i < result.Count; i++)
{
Assert.AreEqual(table.Data[i + 1][0], result[i]["IntValue"]);
Assert.AreEqual(table.Data[i + 1][1], result[i]["StrigValue"]);
Assert.AreEqual(table.Data[i + 1][2], result[i]["DateTimeValue"]);
Assert.AreEqual(table.Data[i + 1][3], result[i]["EnumValue"]);
}
}

/// <summary>
/// 有 null 表頭不匯入。
/// </summary>
[TestMethod]
public void ConvertFromDataWithNullSchema_ShouldReturnCorrectList()
{
// Arrange
var table = new ExcelyTable(new List<IList<object?>>
{
new List<object?> { "IntValue", "StrigValue", "DateTimeValue", null },
new List<object?> { 1, "Text1", DateTime.Parse("2023/1/1"), SampleEnum.Enum1 },
new List<object?> { 2, "Text2", DateTime.Parse("2023/1/2"), SampleEnum.Enum2 },
});
var converter = new DictionaryListTableConverter();

// Act
var result = converter.ConvertFrom(table).ToList();

// Assert
Assert.AreEqual(2, result.Count);
for (int i = 0; i < result.Count; i++)
{
Assert.AreEqual(table.Data[i + 1][0], result[i]["IntValue"]);
Assert.AreEqual(table.Data[i + 1][1], result[i]["StrigValue"]);
Assert.AreEqual(table.Data[i + 1][2], result[i]["DateTimeValue"]);
Assert.AreEqual(table.Data[i + 1][3], result[i]["3"]);
}
}

/// <summary>
/// 自訂表頭測試。
/// </summary>
[TestMethod]
public void ConvertFromDataWithCustomSchema_ShouldReturnCorrectList()
{
// Arrange
var table = new ExcelyTable(new List<IList<object?>>
{
new List<object?> { "IntValue", "StrigValue", "DateTimeValue", "Enum" },
new List<object?> { 1, "Text1", DateTime.Parse("2023/1/1"), SampleEnum.Enum1 },
new List<object?> { 2, "Text2", DateTime.Parse("2023/1/2"), SampleEnum.Enum2 },
});
var options = new DictionaryListTableConverterOptions
{
HasSchema = true,
CustomKeyNamePolicy = (index, field) => field + index,
};
var converter = new DictionaryListTableConverter(options);

// Act
var result = converter.ConvertFrom(table).ToList();

// Assert
Assert.AreEqual(2, result.Count);
for (int i = 0; i < result.Count; i++)
{
Assert.AreEqual(table.Data[i + 1][0], result[i]["IntValue0"]);
Assert.AreEqual(table.Data[i + 1][1], result[i]["StrigValue1"]);
Assert.AreEqual(table.Data[i + 1][2], result[i]["DateTimeValue2"]);
Assert.AreEqual(table.Data[i + 1][3], result[i]["Enum3"]);
}
}

/// <summary>
/// 自訂表頭測試,忽略某些欄位。
/// </summary>
[TestMethod]
public void ConvertFromDataWithCustomSchema_IgnoreSomeField_ShouldReturnCorrectList()
{
// Arrange
var table = new ExcelyTable(new List<IList<object?>>
{
new List<object?> { "IntValue", "StrigValue", "DateTimeValue", "Enum" },
new List<object?> { 1, "Text1", DateTime.Parse("2023/1/1"), SampleEnum.Enum1 },
new List<object?> { 2, "Text2", DateTime.Parse("2023/1/2"), SampleEnum.Enum2 },
});
var options = new DictionaryListTableConverterOptions
{
HasSchema = true,
CustomKeyNamePolicy = (index, field) => field == "Enum" ? null : field,
};
var converter = new DictionaryListTableConverter(options);

// Act
var result = converter.ConvertFrom(table).ToList();

// Assert
Assert.AreEqual(2, result.Count);
for (int i = 0; i < result.Count; i++)
{
Assert.AreEqual(table.Data[i + 1][0], result[i]["IntValue"]);
Assert.AreEqual(table.Data[i + 1][1], result[i]["StrigValue"]);
Assert.AreEqual(table.Data[i + 1][2], result[i]["DateTimeValue"]);
Assert.IsFalse(result[i].ContainsKey("Enum"));
}
}

/// <summary>
/// 不含表頭測試,使用預設邏輯。
/// </summary>
[TestMethod]
public void ConvertFromDataWithoutSchema_ShouldReturnCorrectList()
{
// Arrange
var table = new ExcelyTable(new List<IList<object?>>
{
new List<object?> { 1, "Text1", DateTime.Parse("2023/1/1"), SampleEnum.Enum1 },
new List<object?> { 2, "Text2", DateTime.Parse("2023/1/2"), SampleEnum.Enum2 },
});
var options = new DictionaryListTableConverterOptions
{
HasSchema = false
};
var converter = new DictionaryListTableConverter(options);

// Act
var result = converter.ConvertFrom(table).ToList();

// Assert
Assert.AreEqual(2, result.Count);
for (int i = 0; i < result.Count; i++)
{
Assert.AreEqual(table.Data[i][0], result[i]["0"]);
Assert.AreEqual(table.Data[i][1], result[i]["1"]);
Assert.AreEqual(table.Data[i][2], result[i]["2"]);
Assert.AreEqual(table.Data[i][3], result[i]["3"]);
}
}

/// <summary>
/// 自訂寫入值測試。
/// </summary>
[TestMethod]
public void ConvertFromDataWithPropertyValueSettingPolicy_ShouldReturnCorrectList()
{
#pragma warning disable CS8605 // Unboxing 可能 null 值。
// Arrange
var table = new ExcelyTable(new List<IList<object?>>
{
new List<object?> { "IntValue", "StrigValue", "DateTimeValue", "EnumValue" },
new List<object?> { 1, "Text1", DateTime.Parse("2023/1/1"), SampleEnum.Enum1 },
new List<object?> { 2, "Text2", DateTime.Parse("2023/1/2"), SampleEnum.Enum2 },
});
var options = new DictionaryListTableConverterOptions
{
CustomValuePolicy = (key, value) => key switch
{
"IntValue" => (int)value * 2,
_ => value,
}
};
var converter = new DictionaryListTableConverter(options);

// Act
var result = converter.ConvertFrom(table).ToList();

// Assert
Assert.AreEqual(2, result.Count);
for (int i = 0; i < result.Count; i++)
{
Assert.AreEqual((int)table.Data[i + 1][0] * 2, result[i]["IntValue"]);
Assert.AreEqual(table.Data[i + 1][1], result[i]["StrigValue"]);
Assert.AreEqual(table.Data[i + 1][2], result[i]["DateTimeValue"]);
Assert.AreEqual(table.Data[i + 1][3], result[i]["EnumValue"]);
}
#pragma warning restore CS8605 // Unboxing 可能 null 值。
}
}
}
126 changes: 126 additions & 0 deletions Excely.UnitTests/DictionaryListTableFactoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using Excely.TableFactories;

namespace Excely.UnitTests
{
[TestClass]
public class DictionaryListTableFactoryTests
{
[TestMethod]
public void GetTable_WithDefaultOptions_ShouldIncludeAllPropertiesWithSchema()
{
// Arrange
var factory = new DictionaryListTableFactory();
var testData = new List<Dictionary<string, object?>>
{
new Dictionary<string, object?>
{
{ "Id", 1 },
{ "Name", "Alice" }
}
};

// Act
var table = factory.GetTable(testData);

// Assert
Assert.AreEqual(2, table.MaxRowCount); // Including schema
Assert.AreEqual(2, table.MaxColumnCount); // Id and Name
Assert.AreEqual("Id", table.Data[0][0]);
Assert.AreEqual("Name", table.Data[0][1]);
Assert.AreEqual(1, table.Data[1][0]);
Assert.AreEqual("Alice", table.Data[1][1]);
}

[TestMethod]
public void GetTable_WithOptionsNoSchema_ShouldExcludeSchema()
{
// Arrange
var options = new DictionaryListTableFactoryOptions { WithSchema = false };
var factory = new DictionaryListTableFactory(options);
var testData = new List<Dictionary<string, object?>>
{
new Dictionary<string, object?>
{
{ "Id", 1 },
{ "Name", "Alice" }
}
};

// Act
var table = factory.GetTable(testData);

// Assert
Assert.AreEqual(1, table.MaxRowCount); // Excluding schema
Assert.AreEqual(1, table.Data[0][0]);
Assert.AreEqual("Alice", table.Data[0][1]);
}

[TestMethod]
public void GetTable_WithCustomPropertyShowPolicy_ShouldFilterProperties()
{
// Arrange
var options = new DictionaryListTableFactoryOptions
{
KeyShowPolicy = key => key == "Name"
};
var factory = new DictionaryListTableFactory(options);
var testData = new List<Dictionary<string, object?>>
{
new Dictionary<string, object?>
{
{ "Id", 1 },
{ "Name", "Alice" }
}
};

// Act
var table = factory.GetTable(testData);

// Assert
Assert.AreEqual(2, table.MaxRowCount); // Including schema
Assert.AreEqual(1, table.MaxColumnCount); // Only Name
Assert.AreEqual("Alice", table.Data[1][0]);
}

[TestMethod]
public void GetTable_WithNullList_ShouldThrowArgumentNullException()
{
// Arrange
var factory = new DictionaryListTableFactory();

// Act & Assert
Assert.ThrowsException<System.ArgumentNullException>(() => factory.GetTable(null));
}

[TestMethod]
public void GetTable_WithCustomOrderPolicy_ShouldOrderColumnsAccordingly()
{
// Arrange
var options = new DictionaryListTableFactoryOptions
{
CustomValuePolicy = (key, obj) =>
key == "Name" ? 1 : 2
};
var factory = new DictionaryListTableFactory(options);
var testData = new List<Dictionary<string, object?>>
{
new Dictionary<string, object?>
{
{ "Id", 1 },
{ "Name", "Alice" }
}
};

// Act
var table = factory.GetTable(testData);

// Assert
Assert.AreEqual("Id", table.Data[0][0]);
Assert.AreEqual("Name", table.Data[0][1]);
Assert.AreEqual(2, table.Data[1][0]);
Assert.AreEqual(1, table.Data[1][1]);
}

// 可以根據需要添加更多的測試案例...
}
}
2 changes: 1 addition & 1 deletion Excely/TableConverters/DictionaryListTableConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,6 @@ public class DictionaryListTableConverterOptions
/// 輸入參數為 (Key, 原始值),輸出結果為「應寫入的值」。
/// 預設為原值。
/// </summary>
public Func<string, object?, object?> CustomValuePolicy { get; set; } = (key, obj) => obj;
public Func<string, object?, object?> CustomValuePolicy { get; set; } = (key, value) => value;
}
}

0 comments on commit 8f3a491

Please sign in to comment.