Neman
Neman

Reputation: 1

Failed assertion when validating sorting order

I need help in understanding why does the test fails when sorting by descending/ascending order, and what possible options to fix it?

Here is the failure text :

Expected sortedColumnEntries to be in descending order, but found {"17_2", "14_8", "14_5", "13_2", "10_8", "8_5", "5_13", "5_6", "3_7", "3_3", "3_3", "2_5, ..."} where item at index 0 is in wrong order.

Code(DDT test):

var sortedColumnEntries =
    customPage.GetValuesForColumn(columnName);
if (customPage.Grid.Header[columnName].IsSortButtonAscending) {
    using (new AssertionScope()) {
        customPage.Grid.Header[columnName].IsAscending.Should().BeTrue();
        sortedColumnEntries.Should().BeInAscendingOrder(StringComparer.InvariantCultureIgnoreCase);
    }
} else {
    using (new AssertionScope()) {
        customPage.Grid.Header[columnName].IsSortButtonDescending.Should().BeTrue();
        customPage.Grid.Header[columnName].IsAscending.Should().BeFalse();
        sortedColumnEntries.Should().BeInDescendingOrder(StringComparer.InvariantCultureIgnoreCase);
    }
}

public IEnumerable <string> GetValuesForColumn(string columnName) {
    if (columnName == "Title") {
      return GetTitlesOnCurrentGrid();
    }

    var headers = Grid.Header.HeaderItems.ToList();
    var columnHeader = headers.First(x => x.Text == columnName);
    var columnIndex = headers.IndexOf(columnHeader);
    return Grid.RowItems.Select(i => {
      if (columnName == "Tutor" && i.MultipleTeacherRowItem.Visible) {
        i.MultipleTeacherRowItem.HoverMouse(isLongHover: true);
        return i.MultipleTeacherRowItem.TooltipText;
      }

      return i[columnIndex].Text;
    });
  1. "Title" is a different column therefore the method skips the if statement.
  2. It is worth to be noticed, that the values can also exist under the column as below:
    "-_1"
    "--"

I've tried several options of StringComparer class (such as Ordinal, etc) but nothing helps.

Upvotes: 0

Views: 71

Answers (1)

yangtb
yangtb

Reputation: 29

If you want them to be sorted like the file name in Windows File Explore, either of the options in the StringComparer enumeration won't do what you need. you'll need to use Win32_Api StrCmpLogicalW. It will

Compares two Unicode strings. Digits in the strings are considered as numerical content rather than text. This test is not case-sensitive.

Then, you could use StrCmpLogicalW to implement a IComparer<string>, like this:

public class LogicComparer : IComparer<string>
{
    [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
    private static extern int StrCmpLogicalW(string x, string y);

    public int Compare(string? x, string? y)
    {
        if(x == null && y == null)
            return 0;
        if(x == null)
            return -1;
        if(y == null)
            return 1;
        return StrCmpLogicalW(x, y);
    }
}

And then, it will be OK:

var entries = new List<string>() { "17_9", "14_8", "14_5", "13_2", "10_8", "8_5", "5_13", "5_6", "3_7", "3_3", "3_3", "2_5"};
entries.Should().BeInDescendingOrder(new LogicComparer());

As for why the failure message indicates that index is 0, because the logic of method BeInDescendingOrder, is that:

step1: get the correct descending order:

{"8_5", "5_13", "5_6", "3_7", "3_3", "3_3", "2_5", "17_9", "14_8", "14_5", "13_2", "10_8"}

step2: Compare each element. So, it will find that the first element is incorrent.

Upvotes: 1

Related Questions