Skip to content

Commit

Permalink
Use a cutoff date from BCD for Baseline high (#1333)
Browse files Browse the repository at this point in the history
Fixes #1331.
  • Loading branch information
foolip authored Jul 8, 2024
1 parent 0b13fa3 commit 94050bd
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 81 deletions.
26 changes: 12 additions & 14 deletions packages/compute-baseline/src/baseline/date-utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import assert from "node:assert/strict";

import { Temporal } from "@js-temporal/polyfill";
import { isFuture } from "./date-utils.js";
import { toHighDate, toDateString } from "./date-utils.js";

describe("isFuture", function () {
it("returns true for tomorrow", function () {
const tomorrow = Temporal.Now.plainDateISO().add({ days: 1 });
assert(isFuture(tomorrow));
describe("toHighDate", function () {
it("Jan 1", function () {
assert.equal(toDateString(toHighDate("2020-01-01")), "2022-07-01");
});

it("returns false for yesterday", function () {
const yesterday = Temporal.Now.plainDateISO().subtract({ days: 1 });
assert(isFuture(yesterday) === false);
it("Feb 28", function () {
assert.equal(toDateString(toHighDate("2020-02-28")), "2022-08-28");
});

it("returns false for today", function () {
const now = Temporal.Now.plainDateISO();
assert(isFuture(now) === false);
// Last date for a feature to become Baseline high in YYYY+2 instead of +3.
it("Jun 30", function () {
assert.equal(toDateString(toHighDate("2020-06-30")), "2022-12-30");
});
it("Dec 31", function () {
assert.equal(toDateString(toHighDate("2020-12-31")), "2023-06-30");
});
});
6 changes: 0 additions & 6 deletions packages/compute-baseline/src/baseline/date-utils.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { Temporal } from "@js-temporal/polyfill";
import { BASELINE_LOW_TO_HIGH_DURATION } from "./index.js";

type LowDate = Temporal.PlainDate | string;

export function isFuture(date: Temporal.PlainDate): boolean {
return Temporal.PlainDate.compare(Temporal.Now.plainDateISO(), date) < 0;
}

export function toHighDate(
lowDate: Parameters<typeof Temporal.PlainDate.from>[0],
): Temporal.PlainDate {
Expand Down
27 changes: 12 additions & 15 deletions packages/compute-baseline/src/baseline/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,45 +138,42 @@ describe("computeBaseline", function () {
});

describe("keystoneDateToStatus()", function () {
it('returns "low" for recent dates', function () {
it('returns "low" for date 1 year before cutoff date', function () {
const status = keystoneDateToStatus(
Temporal.Now.plainDateISO().subtract({ days: 7 }),
Temporal.PlainDate.from("2020-01-01"),
Temporal.PlainDate.from("2021-01-01"),
false,
);
assert.equal(status.baseline, "low");
assert.equal(typeof status.baseline_low_date, "string");
assert.equal(status.baseline_low_date, "2020-01-01");
assert.equal(status.baseline_high_date, null);
});

it('returns "high" for long past dates', function () {
it('returns "high" for date 3 years before cutoff date', function () {
const status = keystoneDateToStatus(
Temporal.PlainDate.from("2020-01-01"),
Temporal.PlainDate.from("2024-01-01"),
false,
);
assert.equal(status.baseline, "high");
assert.equal(typeof status.baseline_low_date, "string");
assert.equal(typeof status.baseline_high_date, "string");
assert.equal(status.baseline_low_date, "2020-01-01");
assert.equal(status.baseline_high_date, "2022-07-01");
});

it("returns false for future dates", function () {
it("returns false for null dates", function () {
const status = keystoneDateToStatus(
Temporal.Now.plainDateISO().add({ days: 90 }),
null,
Temporal.PlainDate.from("2020-01-01"),
false,
);
assert.equal(status.baseline, false);
assert.equal(status.baseline_low_date, null);
assert.equal(status.baseline_high_date, null);
});

it("returns false for null dates", function () {
const status = keystoneDateToStatus(null, false);
assert.equal(status.baseline, false);
assert.equal(status.baseline_low_date, null);
assert.equal(status.baseline_high_date, null);
});

it("returns false for discouraged (deprecated, obsolete, etc.) features", function () {
const status = keystoneDateToStatus(
Temporal.PlainDate.from("2020-01-01"),
Temporal.PlainDate.from("2020-01-01"),
true,
);
Expand Down
77 changes: 31 additions & 46 deletions packages/compute-baseline/src/baseline/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Compat, defaultCompat } from "../browser-compat-data/compat.js";
import { feature } from "../browser-compat-data/feature.js";
import { Release } from "../browser-compat-data/release.js";
import { browsers } from "./core-browser-set.js";
import { isFuture, toDateString, toHighDate } from "./date-utils.js";
import { toDateString, toHighDate } from "./date-utils.js";
import { support } from "./support.js";

interface Logger {
Expand Down Expand Up @@ -90,6 +90,14 @@ export function computeBaseline(
},
compat: Compat = defaultCompat,
): SupportDetails {
// A cutoff date approximating "now" is needed to determine when a feature has
// entered Baseline high. We use BCD's __meta.timestamp for this, but any
// "clock" based on the state of the tree that ticks frequently would work.
const timestamp: string = (compat.data as any).__meta.timestamp;
const cutoffDate = Temporal.Instant.from(timestamp)
.toZonedDateTimeISO("UTC")
.toPlainDate();

const { compatKeys } = featureSelector;
const keys = featureSelector.checkAncestors
? compatKeys.flatMap((key) => withAncestors(key, compat))
Expand All @@ -101,11 +109,9 @@ export function computeBaseline(
const keystoneDate = findKeystoneDate(
statuses.flatMap((s) => [...s.support.values()]),
);
const { baseline, baseline_low_date, baseline_high_date, discouraged } =
keystoneDateToStatus(
keystoneDate,
statuses.some((s) => s.discouraged),
);
const discouraged = statuses.some((s) => s.discouraged);
const { baseline, baseline_low_date, baseline_high_date } =
keystoneDateToStatus(keystoneDate, cutoffDate, discouraged);

return {
baseline,
Expand All @@ -123,24 +129,12 @@ export function computeBaseline(
* Compute the Baseline support ("high", "low" or false, dates, and releases)
* for a single compat key.
*/
function calculate(compatKey: string, compat: Compat): SupportDetails {
function calculate(compatKey: string, compat: Compat) {
const f = feature(compatKey);
const s = support(f, browsers(compat));
const keystoneDate = findKeystoneDate([...s.values()]);

const { baseline, baseline_low_date, baseline_high_date, discouraged } =
keystoneDateToStatus(keystoneDate, f.deprecated ?? false);

return {
compatKey,
baseline,
baseline_low_date,
baseline_high_date,
discouraged,
support: s,
toJSON: function () {
return jsonify(this);
},
discouraged: f.deprecated ?? false,
support: support(f, browsers(compat)),
};
}

Expand Down Expand Up @@ -202,41 +196,32 @@ function collateSupport(
*/
export function keystoneDateToStatus(
date: Temporal.PlainDate | null,
cutoffDate: Temporal.PlainDate,
discouraged: boolean,
): {
baseline: BaselineStatus;
baseline_low_date: BaselineDate;
baseline_high_date: BaselineDate;
discouraged: boolean;
} {
let baseline: BaselineStatus;
let baseline_low_date;
let baseline_high_date;

if (discouraged || date === null || isFuture(date)) {
baseline = false;
baseline_low_date = null;
baseline_high_date = null;
discouraged = discouraged;
} else {
baseline = "low";
baseline_low_date = toDateString(date);
baseline_high_date = null;
discouraged = false;
if (date == null || discouraged) {
return {
baseline: false,
baseline_low_date: null,
baseline_high_date: null,
};
}

if (baseline === "low") {
assert(date !== null);
const possibleHighDate = toHighDate(date);
if (isFuture(possibleHighDate)) {
baseline_high_date = null;
} else {
baseline = "high";
baseline_high_date = toDateString(possibleHighDate);
}
let baseline: BaselineStatus = "low";
let baseline_low_date: BaselineDate = toDateString(date);
let baseline_high_date: BaselineDate = null;

const possibleHighDate = toHighDate(date);
if (Temporal.PlainDate.compare(possibleHighDate, cutoffDate) <= 0) {
baseline = "high";
baseline_high_date = toDateString(possibleHighDate);
}

return { baseline, baseline_low_date, baseline_high_date, discouraged };
return { baseline, baseline_low_date, baseline_high_date };
}

/**
Expand Down

0 comments on commit 94050bd

Please sign in to comment.