074123ba2fb70164a7aa364f7c8baf21d70f55a5
braney
  Thu Aug 27 09:04:05 2026 -0700
docent: let expect: check the order rows were drawn in, refs #37892

rows: has been a set test, and exact: true only added "and nothing else",
so no assertion in the language could fail because the rows came back in
the wrong order. ordered: true adds that check: the named rows have to
appear top to bottom in the order given. A row that was not drawn at all
is reported once, by rows:, and skipped here rather than failing twice.
A failure names the first pair that is inverted.

The case that prompted it is #38032, a quickLift target returning its
tracks in the order they were lifted rather than the order they have on
the source. A tour of that bug passed every check on the broken build.

Two tests: ordered asserts the hg38 order, and ordered.xfail names the
same two rows backwards and has to fail, since a flag that cannot fail is
only a second copy of the set test beside it.

diff --git src/hg/utils/docent/tests/README.txt src/hg/utils/docent/tests/README.txt
index b7ddec1bfe5..8d0a5f71c62 100644
--- src/hg/utils/docent/tests/README.txt
+++ src/hg/utils/docent/tests/README.txt
@@ -33,30 +33,34 @@
   composite     clinvar with clinvarCnv hidden: the two-request split (#37953). One
                 request would leave clinvarCnv_sel=1 and the CNV row drawn.
   views         hideKids on the VIEW that holds the subtrack, with the sibling views
                 hidden by name. Also covers the `_sel` checkbox, since the subtrack is
                 `parent wgEncodeRegDnaseSignal off`, and pins the superTrack side effect
                 below.
   views.xfail   the same thing aimed at the COMPOSITE instead, which loses the row.
                 Expected to fail.
   supertrack    varsInPubs hideKids + one member: `exact: true`, because a test that only
                 checked the member was present would pass with all six drawn.
   urllen        {cCREs: hideKids} must not become the 1701-variable, 42,020-character GET
                 that Apache answered with 414. Checks `noText: "Too Long"`, since a 414
                 renders as a perfectly good page; the derive baseline pins it at 3.
   customtrack   addCustomTrack: with inline BED, tabs and newlines surviving the trip.
   scale         a 3x run draws the same rows as a 1x one.
+  ordered       `ordered: true` on rows:, and the fact that a row which was not drawn is
+                reported by rows: alone rather than failing the order check as well.
+  ordered.xfail the same two rows named the wrong way round. Expected to fail -- a flag
+                that cannot fail is not a check, it is a second copy of the set test.
   expectfail    an assertion that is plainly false. Expected to fail -- if it ever passes,
     .xfail      `expect:` has stopped throwing and every other test here means nothing.
   make parity   FAST vs slow, and a rerun, on composite. FAST drops the dwells and the
                 recording and must not change what the page ends up showing; the rerun
                 catches state left behind in the cart.
 
 Two things these tests found
 ----------------------------
 
 Worth knowing before writing more:
 
   * Turning on anything under a superTrack sends `<superTrack>=show`, and every OTHER
     member then comes up at its own trackDb visibility -- so `hide: all` is undone for
     them. views asserts wgEncodeRegMarkH3k27ac comes back, rather than working around it.
     Whether Docent should be cleverer here is an open question, not a settled one.