Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new composition level: "fork" #528

Merged
merged 6 commits into from
Feb 28, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion schema/definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

"seriesComposition": {
"type": "string",
"enum": ["full", "delta"]
"enum": ["full", "delta", "fork"]
},

"forceCurrent": {
Expand Down
2 changes: 1 addition & 1 deletion schema/specs.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"oneOf": [
{
"type": "string",
"pattern": "^https://[^\\s]+(\\s(delta|current|multipage))?$"
"pattern": "^https://[^\\s]+(\\s(delta|fork|current|multipage))?$"
},
{
"type": "object",
Expand Down
5 changes: 5 additions & 0 deletions specs.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@
"https://w3c.github.io/webappsec-trusted-types/dist/spec/",
"https://w3c.github.io/webdriver-bidi/",
"https://w3c.github.io/webrtc-ice/",
{
"url": "https://webassembly.github.io/exception-handling/js-api/",
"shortname": "wasm-js-api-1",
dontcallmedom marked this conversation as resolved.
Show resolved Hide resolved
"seriesComposition": "fork"
},
"https://webbluetoothcg.github.io/web-bluetooth/",
"https://webidl.spec.whatwg.org/",
"https://websockets.spec.whatwg.org/",
Expand Down
5 changes: 4 additions & 1 deletion src/build-index.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,17 @@ async function generateIndex(specs, { previousIndex = null, log = console.log }
log("Prepare initial list of specs...");
specs = specs
// Turn all specs into objects
// (and handle syntactic sugar notation for delta/current flags)
// (and handle syntactic sugar notation for delta/current/fork flags)
.map(spec => {
if (typeof spec === "string") {
const parts = spec.split(" ");
const res = { url: parts[0] };
if (parts[1] === "delta") {
res.seriesComposition = "delta";
}
else if (parts[1] === "fork") {
res.seriesComposition = "fork";
}
else if (parts[1] === "current") {
res.forceCurrent = true;
}
Expand Down
11 changes: 7 additions & 4 deletions src/compute-currentlevel.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* (if needed) properties.
*
* By default, the current level is defined as the last level that is not a
* delta spec, unless a level is explicitly flagged with a "forceCurrent"
* delta/fork spec, unless a level is explicitly flagged with a "forceCurrent"
* property in the list of specs.
*/

Expand All @@ -27,9 +27,12 @@ module.exports = function (spec, list) {

const current = list.reduce((candidate, curr) => {
if (curr.series.shortname === candidate.series.shortname &&
!candidate.forceCurrent &&
curr.seriesComposition !== "delta" &&
(curr.forceCurrent || candidate.seriesComposition === "delta" ||
!candidate.forceCurrent &&
curr.seriesComposition !== "fork" &&
curr.seriesComposition !== "delta" &&
(curr.forceCurrent ||
candidate.seriesComposition === "delta" ||
candidate.seriesComposition === "fork" ||
(curr.seriesVersion || "0") > (candidate.seriesVersion || "0"))) {
return curr;
}
Expand Down
10 changes: 8 additions & 2 deletions src/lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ function shortenDefinition(spec) {
spec.seriesComposition === "delta") {
return `${spec.url} delta`;
}
else if (Object.keys(short).length === 2 &&
spec.seriesComposition === "fork") {
return `${spec.url} fork`;
}
else if (Object.keys(short).length === 2 &&
spec.forceCurrent) {
return `${spec.url} current`;
Expand All @@ -53,7 +57,8 @@ function lintStr(specsStr) {
.map(spec => (typeof spec === "string") ?
{
url: new URL(spec.split(" ")[0]).toString(),
seriesComposition: (spec.split(' ')[1] === "delta") ? "delta" : "full",
seriesComposition: (spec.split(' ')[1] === "delta") ? "delta" :
(spec.split(' ')[1] === "fork") ? "fork" : "full",
forceCurrent: (spec.split(' ')[1] === "current"),
multipage: (spec.split(' ')[1] === "multipage"),
} :
Expand All @@ -74,7 +79,8 @@ function lintStr(specsStr) {
const next = linked.seriesNext ?
linkedList.find(p => p.shortname === linked.seriesNext) :
null;
const isLast = !next || next.seriesComposition === "delta";
const isLast = !next || next.seriesComposition === "delta" ||
dontcallmedom marked this conversation as resolved.
Show resolved Hide resolved
next.seriesComposition === "fork";
if (spec.forceCurrent && isLast) {
spec.forceCurrent = false;
}
Expand Down
16 changes: 16 additions & 0 deletions test/compute-currentlevel.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ describe("compute-currentlevel module", () => {
spec.shortname);
});

it("returns the name of the latest level that is not a fork spec", () => {
const spec = getSpec({ seriesVersion: "1" });
const fork = getSpec({ seriesVersion: "2", seriesComposition: "fork" });
assert.equal(
getCurrentName(spec, [spec, fork]),
spec.shortname);
});

it("gets back to the latest level when spec is a delta spec", () => {
const spec = getSpec({ seriesVersion: "1" });
const delta = getSpec({ seriesVersion: "2", seriesComposition: "delta" });
Expand All @@ -57,6 +65,14 @@ describe("compute-currentlevel module", () => {
spec.shortname);
});

it("gets back to the latest level when spec is a fork spec", () => {
const spec = getSpec({ seriesVersion: "1" });
const fork = getSpec({ seriesVersion: "2", seriesComposition: "fork" });
assert.equal(
getCurrentName(fork, [spec, fork]),
spec.shortname);
});

it("returns the spec name if it is flagged as current", () => {
const spec = getSpec({ seriesVersion: "1", forceCurrent: true });
const last = getSpec({ seriesVersion: "2" });
Expand Down
6 changes: 6 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ describe("List of specs", () => {
assert.deepStrictEqual(wrong, []);
});

it("has previous links for all fork specs", () => {
const wrong = specs.filter(s =>
s.seriesComposition === "fork" && !s.seriesPrevious);
assert.deepStrictEqual(wrong, []);
});

it("has previous links that can be resolved to a spec", () => {
const wrong = specs.filter(s =>
s.seriesPrevious && !specs.find(p => p.shortname === s.seriesPrevious));
Expand Down
19 changes: 19 additions & 0 deletions test/lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ describe("Linter", () => {
assert.equal(lintStr(toStr(specs)), null);
});

it("passes if specs contains a URL with a fork spec", () => {
const specs = [
"https://www.w3.org/TR/spec-1/",
"https://www.w3.org/TR/spec-2/ fork"
];
assert.equal(lintStr(toStr(specs)), null);
});

it("passes if specs contains a URL with a spec flagged as current", () => {
const specs = [
"https://www.w3.org/TR/spec-1/ current",
Expand Down Expand Up @@ -125,6 +133,17 @@ describe("Linter", () => {
]));
});

it("lints an object with a useless current flag (fork version)", () => {
const specs = [
"https://www.w3.org/TR/spec-1/ current",
"https://www.w3.org/TR/spec-2/ fork"
];
assert.equal(lintStr(toStr(specs)), toStr([
"https://www.w3.org/TR/spec-1/",
"https://www.w3.org/TR/spec-2/ fork",
]));
});

it("lints an object with a 'full' flag", () => {
const specs = [
{ "url": "https://www.w3.org/TR/spec/", "seriesComposition": "full" }
Expand Down
24 changes: 22 additions & 2 deletions test/specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ function specs2objects(specs) {
.map(spec => (typeof spec === "string") ?
{
url: new URL(spec.split(" ")[0]).toString(),
seriesComposition: (spec.split(' ')[1] === "delta") ? "delta" : "full",
seriesComposition: (spec.split(' ')[1] === "delta") ? "delta" :
(spec.split(' ')[1] === "fork") ? "fork" : "full",
forceCurrent: (spec.split(' ')[1] === "current"),
multipage: (spec.split(' ')[1] === "multipage"),
} :
Expand Down Expand Up @@ -172,7 +173,7 @@ describe("Input list", () => {
it("does not have a delta spec without a previous full spec", () => {
const fullPrevious = (spec, list) => {
const previous = list.find(s => s.shortname === spec.seriesPrevious);
if (previous && previous.seriesComposition === "delta") {
if (previous && previous.seriesComposition && previous.seriesComposition !== "full") {
return fullPrevious(previous, list);
}
return previous;
Expand All @@ -182,12 +183,31 @@ describe("Input list", () => {
assert.strictEqual(deltaWithoutFull[0], undefined);
});

it("does not have a fork spec without a previous full spec", () => {
const fullPrevious = (spec, list) => {
const previous = list.find(s => s.shortname === spec.seriesPrevious);
if (previous && previous.seriesComposition !== "full") {
return fullPrevious(previous, list);
}
return previous;
};
const forkWithoutFull = specs2LinkedList(specs)
.filter((s, _, list) => s.seriesComposition === "fork" && !fullPrevious(s, list));
assert.strictEqual(forkWithoutFull[0], undefined);
});

it("does not have a delta spec flagged as 'current'", () => {
const deltaCurrent = specs2LinkedList(specs)
.filter(s => s.forceCurrent && s.seriesComposition === "delta");
assert.strictEqual(deltaCurrent[0], undefined);
});

it("does not have a fork spec flagged as 'current'", () => {
const forkCurrent = specs2LinkedList(specs)
.filter(s => s.forceCurrent && s.seriesComposition === "fork");
assert.strictEqual(forkCurrent[0], undefined);
});

it("has only one spec flagged as 'current' per series shortname", () => {
const linkedList = specs2LinkedList(specs);
const problematicCurrent = linkedList
Expand Down