f9f813c4330857fed2ed6008e6d6e9eb54d2474a
galt
  Fri Mar 28 04:51:53 2025 -0700
fixing slNameSort in list.c for hubApi, refreshed expected output lists. fixes #26947

diff --git src/hg/hubApi/tests/jsonConsumer.pl src/hg/hubApi/tests/jsonConsumer.pl
index b5513d45417..7c8dd1e29af 100755
--- src/hg/hubApi/tests/jsonConsumer.pl
+++ src/hg/hubApi/tests/jsonConsumer.pl
@@ -124,31 +124,31 @@
     # if less than a second then sleep for the remainder of the second
     if($diff < 1) {
       Time::HiRes::sleep(1-$diff);
     }
     # reset
     $lastRequestTime = Time::HiRes::time();
     $requestCount = 0;
   }
 
   $endpoint =~ s#^/##;
   my $url = "$server/$endpoint";
   my $argSeparator = ";";
 
   if(%{$parameters}) {
     my @params;
-    foreach my $key (keys %{$parameters}) {
+    foreach my $key (sort {$a cmp $b} keys %{$parameters}) {
       my $value = $parameters->{$key};
       push(@params, "$key=$value");
     }
     my $param_string = join(';', @params);
     $url.= '?'.$param_string;
   } else {
     if ($debug || $measureTiming || $jsonOutputArrays || length($maxItemsOutput) ) {
      $argSeparator = "?";
    }
   }
   if ($debug) { $url .= "${argSeparator}debug=1"; }
   if ($measureTiming) { $url .= "${argSeparator}measureTiming=1"; }
   if ($jsonOutputArrays) { $url .= "${argSeparator}jsonOutputArrays=1"; }
   if ($revComp) { $url .= "${argSeparator}revComp=1"; }
   if (length($maxItemsOutput)) { $url .= "${argSeparator}maxItemsOutput=$maxItemsOutput"; }
@@ -208,39 +208,39 @@
     next if ($topKey eq "downloadTimeStamp");
     next if ($topKey eq "botDelay");
     next if ($topKey eq "dataTime");
     next if ($topKey eq "dataTimeStamp");
     my $value = $topHash->{$topKey};
     $value = "<array>" if (ref($value) eq "ARRAY");
     $value = "<hash>" if (ref($value) eq "HASH");
     printf "\"%s\":\"%s\"\n", $topKey,$value;
   }
 }
 
 #############################################################################
 sub checkError($$$) {
   my ($json, $endpoint, $expect) = @_;
   my $jsonReturn = performJsonAction($endpoint, "");
-#   printf "%s", $json->pretty->encode( $jsonReturn );
+#   printf "%s", $json->canonical()->pretty->encode( $jsonReturn );
   if (! defined($jsonReturn->{'error'}) ) {
      printf "ERROR: no error received from endpoint: '%s', received:\n", $endpoint;
-     printf "%s", $json->pretty->encode( $jsonReturn );
+     printf "%s", $json->canonical()->pretty->encode( $jsonReturn );
   } else {
      if ($jsonReturn->{'error'} ne "$expect '$endpoint'") {
 	printf "incorrect error received from endpoint '%s':\n\t'%s'\n", $endpoint, $jsonReturn->{'error'};
      }
-     printf "%s", $json->pretty->encode( $jsonReturn );
+     printf "%s", $json->canonical()->pretty->encode( $jsonReturn );
   }
 }
 
 #############################################################################
 sub verifyCommandProcessing()
 {
     my $json = JSON->new;
     # verify command processing can detected bad input
     my $endpoint = "/list/noSubCommand";
     my $expect = "do not recognize endpoint function:";
     checkError($json, $endpoint,$expect);
 }	#	sub verifyCommandProcessing()
 
 #############################################################################
 #  Find the highest chromStart in the returned to data to obtain a continuation
@@ -352,53 +352,55 @@
      if (length($track)) {
 	$parameters{"track"} = "$track";
      }
      if (length($start)) {
 	$parameters{"start"} = "$start";
      }
      if (length($end)) {
 	$parameters{"end"} = "$end";
      }
      #	Pass along any bogus request just to test the error handling.
      if ($trackDump) {
         $errReturn = trackDump($endpoint, \%parameters);
      } else {
         $jsonReturn = performJsonAction($endpoint, \%parameters);
         $errReturn = 1 if (defined ($jsonReturn->{'error'}));
-        printf "%s", $json->pretty->encode( $jsonReturn );
+        printf "%s", $json->canonical()->pretty->encode( $jsonReturn );
      }
   } else {
     printf STDERR "ERROR: no endpoint given ?\n";
     usage();
     exit 255;
   }
   return $errReturn;
 }	# sub processEndPoint()
 
 ###########################################################################
 ### test /list/publicHubs and /list/ucscGenomes
 sub test0() {
 
 my $json = JSON->new;
 my $jsonReturn = {};
 
+# verify command processing can detected bad input
+# /list/noSubCommand
 verifyCommandProcessing();	# check 'command' and 'subCommand'
 
 $jsonReturn = performJsonAction("/list/publicHubs", "");
 
 # this prints everything out indented nicely:
-# printf "%s", $json->pretty->encode( $jsonReturn );
+# printf "%s", $json->canonical()->pretty->encode( $jsonReturn );
 
 # exit 255;
 # __END__
 
 #	"dataTimeStamp" : 1552320994,
 #	"downloadTime" : "2019:03:26T21:40:10Z",
 #	"botDelay" : 2,
 #	"downloadTimeStamp" : 1553636410,
 #	"dataTime" : "2019-03-11T09:16:34"
 
 # look for the specific public hub named "Plants" to print out
 # for a verify test case
 #
 if (ref($jsonReturn) eq "HASH") {
   topLevelKeys($jsonReturn);