Upstream ClosedXML/ClosedXML state of the touched files before f8af6b544a

This commit is contained in:
upstream committed 2026-09-02 11:15:38 +02:00
commit 8d5ee56081
5 files changed
+315

No files matched your search

@@ -0,0 +1,233 @@
using System;
using ClosedXML.Excel;
using NUnit.Framework;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
namespace ClosedXML.Tests.Excel.ConditionalFormats
{
[TestFixture]
public class ConditionalFormatTests
{
[Test]
public void MaintainConditionalFormattingOrder()
{
// The input file contains duplicates of same dxf and thus the output also contains some duplicate dxf.
TestHelper.LoadSaveAndCompare(
@"Other\StyleReferenceFiles\ConditionalFormattingOrder\inputfile.xlsx",
@"Other\StyleReferenceFiles\ConditionalFormattingOrder\ConditionalFormattingOrder.xlsx");
}
[TestCase(true, 7)]
[TestCase(false, 8)]
public void SaveOptionAffectsConsolidationConditionalFormatRanges(bool consolidateConditionalFormatRanges, int expectedCount)
{
var options = new SaveOptions
{
ConsolidateConditionalFormatRanges = consolidateConditionalFormatRanges
};
var wb = new XLWorkbook();
var ws = wb.AddWorksheet("Sheet");
ws.Range("D2:D3").AddConditionalFormat().DataBar(XLColor.Red).LowestValue().HighestValue();
ws.Range("B2:B3").AddConditionalFormat().DataBar(XLColor.Red).LowestValue().HighestValue();
ws.Range("E2:E6").AddConditionalFormat().ColorScale().LowestValue(XLColor.Red).HighestValue(XLColor.Blue);
ws.Range("F2:F6").AddConditionalFormat().ColorScale().LowestValue(XLColor.Red).HighestValue(XLColor.Blue);
ws.Range("G2:G7").AddConditionalFormat().WhenIsUnique().Fill.SetBackgroundColor(XLColor.Blue);
ws.Range("H2:H7").AddConditionalFormat().WhenIsUnique().Fill.SetBackgroundColor(XLColor.Blue);
ws.Range("I2:I6").AddConditionalFormat().WhenContains("test");
ws.Range("J2:J6").AddConditionalFormat().WhenContains("test");
using (var ms = new MemoryStream())
{
wb.SaveAs(ms, options);
var wb_saved = new XLWorkbook(ms);
Assert.AreEqual(expectedCount, wb_saved.Worksheet("Sheet").ConditionalFormats.Count());
}
}
[TestCase(true, 1)]
[TestCase(false, 2)]
public void SaveOptionAffectsConsolidationDataValidationRanges(bool consolidateDataValidationRanges, int expectedCount)
{
var options = new SaveOptions
{
ConsolidateDataValidationRanges = consolidateDataValidationRanges
};
var wb = new XLWorkbook();
var ws = wb.AddWorksheet("Sheet");
ws.Range("C2:C5").CreateDataValidation().Decimal.Between(1, 5);
ws.Range("D2:D5").CreateDataValidation().Decimal.Between(1, 5);
using (var ms = new MemoryStream())
{
wb.SaveAs(ms, options);
var wb_saved = new XLWorkbook(ms);
Assert.AreEqual(expectedCount, wb_saved.Worksheet("Sheet").DataValidations.Count());
}
}
[TestCase("en-US")]
[TestCase("fr-FR")]
[TestCase("ru-RU")]
public void SaveConditionalFormat_CultureIndependent(string culture)
{
using (var ms = new MemoryStream())
{
var expectedValue = 1.5;
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(culture);
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var i = 1;
ws.Cell(i++, 1).AddConditionalFormat().WhenEquals(expectedValue).Fill.SetBackgroundColor(XLColor.Red);
ws.Cell(i++, 1).AddConditionalFormat().WhenNotEquals(expectedValue).Fill.SetBackgroundColor(XLColor.Red);
ws.Cell(i++, 1).AddConditionalFormat().WhenGreaterThan(expectedValue).Fill.SetBackgroundColor(XLColor.Red);
ws.Cell(i++, 1).AddConditionalFormat().WhenLessThan(expectedValue).Fill.SetBackgroundColor(XLColor.Red);
ws.Cell(i++, 1).AddConditionalFormat().WhenEqualOrGreaterThan(expectedValue).Fill.SetBackgroundColor(XLColor.Red);
ws.Cell(i++, 1).AddConditionalFormat().WhenEqualOrLessThan(expectedValue).Fill.SetBackgroundColor(XLColor.Red);
ws.Cell(i++, 1).AddConditionalFormat().WhenBetween(expectedValue, expectedValue).Fill.SetBackgroundColor(XLColor.Red);
ws.Cell(i++, 1).AddConditionalFormat().WhenNotBetween(expectedValue, expectedValue).Fill.SetBackgroundColor(XLColor.Red);
wb.SaveAs(ms);
}
using (var wb = new XLWorkbook(ms))
{
var ws = wb.Worksheets.First();
var conditionalFormatValues = ws.ConditionalFormats
.SelectMany(cf => cf.Values.Values)
.Select(v => v.Value)
.Distinct();
Assert.AreEqual(1, conditionalFormatValues.Count());
Assert.AreEqual("1.5", conditionalFormatValues.Single());
}
}
}
[Test]
public void CellIs_type_reads_only_required_formula_arguments()
{
// The CellIs uses formula tags as arguments. Some producers generate extra empty
// formula tags and ClosedXml should be able to load CellIs conditional formatting
// with such extra tags without an exception. The test file has been modified to
// include extra formula tags and test checks that extra tags are ignored.
TestHelper.LoadAndAssert((_, ws) =>
{
AssertFormulaArgs(ws, XLCFOperator.Between, "$D$2", "$E$2");
AssertFormulaArgs(ws, XLCFOperator.NotBetween, "$D$3", "$E$3");
AssertFormulaArgs(ws, XLCFOperator.GreaterThan, "$D$4");
AssertFormulaArgs(ws, XLCFOperator.LessThan, "$D$5");
AssertFormulaArgs(ws, XLCFOperator.Equal, "$D$6");
}, @"Other\ConditionalFormats\Extra_formulas_CellIs_type.xlsx");
static void AssertFormulaArgs(IXLWorksheet ws, XLCFOperator cfOperator, params string[] expectedFormulas)
{
var cf = ws.ConditionalFormats.Single(cf => cf.ConditionalFormatType == XLConditionalFormatType.CellIs && cf.Operator == cfOperator);
Assert.AreEqual(expectedFormulas.Length, cf.Values.Count);
CollectionAssert.AreEqual(expectedFormulas, cf.Values.Select(v => v.Value.Value));
}
}
[Test]
public void Expression_type_skips_empty_formula_tags()
{
// The Expression uses formula tag as arguments. Some producers generate extra empty
// formula tags and ClosedXml should be able to load Expression conditional formatting
// with such extra tags without an exception. The test file has been modified to
// include extra formula tags and test checks that extra tags are ignored.
TestHelper.LoadAndAssert((_, ws) =>
{
AssertFormulaArgs(ws, "A1:A1", "$C$1=5");
AssertFormulaArgs(ws, "A2:A2", "$C$2=4");
}, @"Other\ConditionalFormats\Extra_formulas_Expression_type.xlsx");
static void AssertFormulaArgs(IXLWorksheet ws, string range, string expectedFormula)
{
var cf = ws.ConditionalFormats.Single(cf => cf.ConditionalFormatType == XLConditionalFormatType.Expression && cf.Range.RangeAddress.ToString() == range);
Assert.AreEqual(1, cf.Values.Count);
CollectionAssert.AreEqual(expectedFormula, cf.Values[1].Value);
}
}
[Test]
public void Range_setter_throws_on_range_from_different_worksheet()
{
using var wb = new XLWorkbook();
var ws1 = wb.AddWorksheet();
var cf = ws1.Range("A1").AddConditionalFormat();
var ws2 = wb.AddWorksheet();
var differentSheetRange = ws2.Range("B5");
Assert.Throws<ArgumentException>(() => cf.Range = differentSheetRange);
}
[Test]
public void Ranges_setter_throws_on_range_from_different_worksheet()
{
using var wb = new XLWorkbook();
var ws1 = wb.AddWorksheet();
var cf = ws1.Range("A1").AddConditionalFormat();
var ranges = ws1.Ranges("B1");
var differentSheetRange = wb.AddWorksheet().Range("C1");
ranges.Add(differentSheetRange);
Assert.That(() => cf.Ranges = ranges, Throws.TypeOf<ArgumentException>().With.Message.Contains("must be from worksheet"));
}
[Test]
public void Ranges_setter_throws_on_empty_ranges()
{
using var wb = new XLWorkbook();
var ws1 = wb.AddWorksheet();
var cf = ws1.Range("A1").AddConditionalFormat();
var emptyRanges = ws1.Ranges("");
Assert.That(() => cf.Ranges = emptyRanges, Throws.TypeOf<ArgumentException>().With.Message.Contains("empty"));
}
[Test]
public void Text_formats_are_loaded_as_value()
{
// Issue #2690: Ensure that CF for text are loaded as a value and not as a formula.
TestHelper.CreateSaveLoadAssert(
(_, ws) =>
{
ws.AddConditionalFormat().WhenContains("Contains")
.Fill.SetBackgroundColor(XLColor.Red);
ws.AddConditionalFormat().WhenNotContains("Not Contains")
.Fill.SetBackgroundColor(XLColor.Green);
ws.AddConditionalFormat().WhenStartsWith("Starts With")
.Fill.SetBackgroundColor(XLColor.Blue);
ws.AddConditionalFormat().WhenEndsWith("Ends With")
.Fill.SetBackgroundColor(XLColor.Black);
},
(_, ws) =>
{
AssertTextCfValue(ws, XLConditionalFormatType.ContainsText, "Contains");
AssertTextCfValue(ws, XLConditionalFormatType.NotContainsText, "Not Contains");
AssertTextCfValue(ws, XLConditionalFormatType.StartsWith, "Starts With");
AssertTextCfValue(ws, XLConditionalFormatType.EndsWith, "Ends With");
});
return;
static void AssertTextCfValue(IXLWorksheet ws, XLConditionalFormatType type, string text)
{
var cf = ws.ConditionalFormats.Single(x => x.ConditionalFormatType == type);
Assert.AreEqual(1, cf.Values.Count);
Assert.AreEqual(text, cf.Values[1].Value);
Assert.IsFalse(cf.Values[1].IsFormula);
}
}
}
}