Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this line is key. Everything else was the follow-on effects.

}

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);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pulled out discouraged, previously it was passed into keystoneDateToStatus only to be returned unchanged.

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);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminating this call to keystoneDateToStatus made this change a bit simpler, and the information wasn't used anyway.


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