tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

compare.ts (3528B)


      1 import { TestParams } from '../../framework/fixture.js';
      2 import { assert, objectEquals } from '../../util/util.js';
      3 import { paramKeyIsPublic } from '../params_utils.js';
      4 
      5 import { TestQuery } from './query.js';
      6 
      7 export const enum Ordering {
      8  Unordered,
      9  StrictSuperset,
     10  Equal,
     11  StrictSubset,
     12 }
     13 
     14 /**
     15 * Compares two queries for their ordering (which is used to build the tree).
     16 *
     17 * See src/unittests/query_compare.spec.ts for examples.
     18 */
     19 export function compareQueries(a: TestQuery, b: TestQuery): Ordering {
     20  if (a.suite !== b.suite) {
     21    return Ordering.Unordered;
     22  }
     23 
     24  const filePathOrdering = comparePaths(a.filePathParts, b.filePathParts);
     25  if (filePathOrdering !== Ordering.Equal || a.isMultiFile || b.isMultiFile) {
     26    return compareOneLevel(filePathOrdering, a.isMultiFile, b.isMultiFile);
     27  }
     28  assert('testPathParts' in a && 'testPathParts' in b);
     29 
     30  const testPathOrdering = comparePaths(a.testPathParts, b.testPathParts);
     31  if (testPathOrdering !== Ordering.Equal || a.isMultiTest || b.isMultiTest) {
     32    return compareOneLevel(testPathOrdering, a.isMultiTest, b.isMultiTest);
     33  }
     34  assert('params' in a && 'params' in b);
     35 
     36  const paramsPathOrdering = comparePublicParamsPaths(a.params, b.params);
     37  if (paramsPathOrdering !== Ordering.Equal || a.isMultiCase || b.isMultiCase) {
     38    return compareOneLevel(paramsPathOrdering, a.isMultiCase, b.isMultiCase);
     39  }
     40  return Ordering.Equal;
     41 }
     42 
     43 /**
     44 * Compares a single level of a query.
     45 *
     46 * "IsBig" means the query is big relative to the level, e.g. for test-level:
     47 *   - Anything >= `suite:a,*` is big
     48 *   - Anything <= `suite:a:*` is small
     49 */
     50 function compareOneLevel(ordering: Ordering, aIsBig: boolean, bIsBig: boolean): Ordering {
     51  assert(ordering !== Ordering.Equal || aIsBig || bIsBig);
     52  if (ordering === Ordering.Unordered) return Ordering.Unordered;
     53  if (aIsBig && bIsBig) return ordering;
     54  if (!aIsBig && !bIsBig) return Ordering.Unordered; // Equal case is already handled
     55  // Exactly one of (a, b) is big.
     56  if (aIsBig && ordering !== Ordering.StrictSubset) return Ordering.StrictSuperset;
     57  if (bIsBig && ordering !== Ordering.StrictSuperset) return Ordering.StrictSubset;
     58  return Ordering.Unordered;
     59 }
     60 
     61 /**
     62 * Compare two file paths, or file-local test paths, returning an Ordering between the two.
     63 */
     64 export function comparePaths(a: readonly string[], b: readonly string[]): Ordering {
     65  const shorter = Math.min(a.length, b.length);
     66 
     67  for (let i = 0; i < shorter; ++i) {
     68    if (a[i] !== b[i]) {
     69      return Ordering.Unordered;
     70    }
     71  }
     72  if (a.length === b.length) {
     73    return Ordering.Equal;
     74  } else if (a.length < b.length) {
     75    return Ordering.StrictSuperset;
     76  } else {
     77    return Ordering.StrictSubset;
     78  }
     79 }
     80 
     81 export function comparePublicParamsPaths(a: TestParams, b: TestParams): Ordering {
     82  const aKeys = Object.keys(a).filter(k => paramKeyIsPublic(k));
     83  const commonKeys = new Set(aKeys.filter(k => k in b));
     84 
     85  for (const k of commonKeys) {
     86    // Treat +/-0.0 as different query by distinguishing them in objectEquals
     87    if (!objectEquals(a[k], b[k], true)) {
     88      return Ordering.Unordered;
     89    }
     90  }
     91  const bKeys = Object.keys(b).filter(k => paramKeyIsPublic(k));
     92  const aRemainingKeys = aKeys.length - commonKeys.size;
     93  const bRemainingKeys = bKeys.length - commonKeys.size;
     94  if (aRemainingKeys === 0 && bRemainingKeys === 0) return Ordering.Equal;
     95  if (aRemainingKeys === 0) return Ordering.StrictSuperset;
     96  if (bRemainingKeys === 0) return Ordering.StrictSubset;
     97  return Ordering.Unordered;
     98 }