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

Fetch spec info from W3C API, Specref or the spec #22

Merged
merged 3 commits into from
Apr 1, 2020
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
13 changes: 13 additions & 0 deletions .github/workflows/lint-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
on: pull_request
name: lint
jobs:
lint:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 12.x
- run: npm ci
- run: npm run test-pr
- run: npm run lint
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
on: [push, pull_request]
on: push
dontcallmedom marked this conversation as resolved.
Show resolved Hide resolved
name: lint
jobs:
lint:
Expand Down
2 changes: 1 addition & 1 deletion lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const computeShortname = require("./src/compute-shortname.js");
const computePrevNext = require("./src/compute-prevnext.js");

const schema = require("./schema/specs.json");
const dfnsSchema = require("./schema/dfns.json");
const dfnsSchema = require("./schema/definitions.json");
const Ajv = require("ajv");
const ajv = new Ajv();
const validate = ajv.addSchema(dfnsSchema).compile(schema);
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"fetch-info": "node src/fetch-info.js > specs-info.json",
"lint": "node lint.js",
"lint-fix": "node lint.js --fix",
"test": "mocha"
"test": "mocha",
"test-pr": "mocha --exclude test/fetch-info-w3c.js"
},
"devDependencies": {
"ajv": "^6.11.0",
Expand Down
4 changes: 2 additions & 2 deletions schema/dfns.json → schema/definitions.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"$schema": "http://json-schema.org/schema#",
"$id": "https://github.com/w3c/browser-specs/tree/master/schema/dfns.json",
"$id": "https://github.com/w3c/browser-specs/tree/master/schema/definitions.json",

"dfns": {
"proptype": {
"url": {
"type": "string",
"format": "uri"
Expand Down
24 changes: 12 additions & 12 deletions schema/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@
"items": {
"type": "object",
"properties": {
"url": { "$ref": "dfns.json#/dfns/url" },
"name": { "$ref": "dfns.json#/dfns/name" },
"shortname": { "$ref": "dfns.json#/dfns/shortname" },
"level": { "$ref": "dfns.json#/dfns/level" },
"levelComposition": { "$ref": "dfns.json#/dfns/levelComposition" },
"currentLevel": { "$ref": "dfns.json#/dfns/name" },
"previousLevel": { "$ref": "dfns.json#/dfns/name" },
"nextLevel": { "$ref": "dfns.json#/dfns/name" },
"edUrl": { "$ref": "dfns.json#/dfns/url" },
"trUrl": { "$ref": "dfns.json#/dfns/url" },
"title": { "$ref": "dfns.json#/dfns/title" },
"source": { "$ref": "dfns.json#/dfns/source" }
"url": { "$ref": "definitions.json#/proptype/url" },
"name": { "$ref": "definitions.json#/proptype/name" },
"shortname": { "$ref": "definitions.json#/proptype/shortname" },
"level": { "$ref": "definitions.json#/proptype/level" },
"levelComposition": { "$ref": "definitions.json#/proptype/levelComposition" },
"currentLevel": { "$ref": "definitions.json#/proptype/name" },
"previousLevel": { "$ref": "definitions.json#/proptype/name" },
"nextLevel": { "$ref": "definitions.json#/proptype/name" },
"edUrl": { "$ref": "definitions.json#/proptype/url" },
"trUrl": { "$ref": "definitions.json#/proptype/url" },
"title": { "$ref": "definitions.json#/proptype/title" },
"source": { "$ref": "definitions.json#/proptype/source" }
},
"required": ["url", "name", "shortname", "currentLevel", "title", "source"],
"additionalProperties": false
Expand Down
8 changes: 4 additions & 4 deletions schema/specs-info.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
"additionalProperties": {
"type": "object",
"properties": {
"edUrl": { "$ref": "dfns.json#/dfns/url" },
"trUrl": { "$ref": "dfns.json#/dfns/url" },
"title": { "$ref": "dfns.json#/dfns/title" },
"source": { "$ref": "dfns.json#/dfns/source" }
"edUrl": { "$ref": "definitions.json#/proptype/url" },
"trUrl": { "$ref": "definitions.json#/proptype/url" },
"title": { "$ref": "definitions.json#/proptype/title" },
"source": { "$ref": "definitions.json#/proptype/source" }
},
"required": ["title", "source"],
"additionalProperties": false
Expand Down
10 changes: 5 additions & 5 deletions schema/specs.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
{
"type": "object",
"properties": {
"url": { "$ref": "dfns.json#/dfns/url" },
"name": { "$ref": "dfns.json#/dfns/name" },
"shortname": { "$ref": "dfns.json#/dfns/shortname" },
"level": { "$ref": "dfns.json#/dfns/level" },
"levelComposition": { "$ref": "dfns.json#/dfns/levelComposition" },
"url": { "$ref": "definitions.json#/proptype/url" },
"name": { "$ref": "definitions.json#/proptype/name" },
"shortname": { "$ref": "definitions.json#/proptype/shortname" },
"level": { "$ref": "definitions.json#/proptype/level" },
"levelComposition": { "$ref": "definitions.json#/proptype/levelComposition" },
"forceCurrent": { "type": "boolean" }
},
"required": ["url"],
Expand Down
118 changes: 118 additions & 0 deletions test/fetch-info-w3c.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/**
* Tests for the fetch-info module that require a W3C API key
*
* These tests are separated from the tests that do not require a W3C API key
* because the key cannot be exposed on pull requests from forked repositories
* on GitHub.
*/

const assert = require("assert");
const fetchInfo = require("../src/fetch-info.js");

const w3cApiKey = (function () {
try {
return require("../config.json").w3cApiKey;
}
catch (err) {
return null;
}
})();


describe("fetch-info module (with W3C API key)", function () {
// Tests need to send network requests
this.slow(5000);
this.timeout(30000);

function getW3CSpec(name) {
return { name, url: `https://www.w3.org/TR/${name}/` };
}

describe("W3C API key", () => {
it("is defined otherwise tests cannot pass", () => {
assert.ok(w3cApiKey);
});
});


describe("fetch from W3C API", () => {
it("works on a TR spec", async () => {
const spec = getW3CSpec("hr-time-2");
const info = await fetchInfo([spec], { w3cApiKey });
assert.ok(info[spec.name]);
assert.equal(info[spec.name].source, "w3c");
assert.equal(info[spec.name].trUrl, spec.url);
assert.equal(info[spec.name].edUrl, "https://w3c.github.io/hr-time/");
assert.equal(info[spec.name].title, "High Resolution Time Level 2");
});

it("can operate on multiple specs at once", async () => {
const spec = getW3CSpec("hr-time-2");
const other = getW3CSpec("presentation-api");
const info = await fetchInfo([spec, other], { w3cApiKey });
assert.ok(info[spec.name]);
assert.equal(info[spec.name].source, "w3c");
assert.equal(info[spec.name].trUrl, spec.url);
assert.equal(info[spec.name].edUrl, "https://w3c.github.io/hr-time/");
assert.equal(info[spec.name].title, "High Resolution Time Level 2");

assert.ok(info[other.name]);
assert.equal(info[other.name].source, "w3c");
assert.equal(info[other.name].trUrl, other.url);
assert.equal(info[other.name].edUrl, "https://w3c.github.io/presentation-api/");
assert.equal(info[other.name].title, "Presentation API");
});

it("throws when W3C API key is invalid", async () => {
assert.rejects(
fetchInfo([getW3CSpec("selectors-3")], { w3cApiKey: "invalid" }),
/^W3C API returned an error, status code is 403$/);
});
});


describe("fetch from Specref", () => {
it("works on a WHATWG spec", async () => {
const spec = {
url: "https://dom.spec.whatwg.org/",
name: "dom"
};
const info = await fetchInfo([spec], { w3cApiKey });
assert.ok(info[spec.name]);
assert.equal(info[spec.name].source, "specref");
assert.equal(info[spec.name].edUrl, "https://dom.spec.whatwg.org/");
assert.equal(info[spec.name].title, "DOM Standard");
});
});


describe("fetch from all sources", () => {
it("merges info from sources", async () => {
const w3c = getW3CSpec("presentation-api");
const whatwg = {
url: "https://html.spec.whatwg.org/multipage/",
name: "html"
};
const other = {
url: "https://tabatkins.github.io/bikeshed/",
name: "bikeshed"
};
const info = await fetchInfo([w3c, whatwg, other], { w3cApiKey });
assert.ok(info[w3c.name]);
assert.equal(info[w3c.name].source, "w3c");
assert.equal(info[w3c.name].trUrl, w3c.url);
assert.equal(info[w3c.name].edUrl, "https://w3c.github.io/presentation-api/");
assert.equal(info[w3c.name].title, "Presentation API");

assert.ok(info[whatwg.name]);
assert.equal(info[whatwg.name].source, "specref");
assert.equal(info[whatwg.name].edUrl, whatwg.url);
assert.equal(info[whatwg.name].title, "HTML Standard");

assert.ok(info[other.name]);
assert.equal(info[other.name].source, "spec");
assert.equal(info[other.name].edUrl, other.url);
assert.equal(info[other.name].title, "Bikeshed Documentation");
});
});
});
97 changes: 11 additions & 86 deletions test/fetch-info.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
/**
* Tests for the fetch-info module that do not require a W3C API key
*
* These tests are separated from the tests that require a W3C API key because
* the key cannot be exposed on pull requests from forked repositories on
* GitHub.
*/

const assert = require("assert");
const fetchInfo = require("../src/fetch-info.js");

const w3cApiKey = (function () {
try {
return require("../config.json").w3cApiKey;
}
catch (err) {
return null;
}
})();


describe("fetch-info module", function () {
describe("fetch-info module (without W3C API key)", function () {
// Tests need to send network requests
this.slow(5000);
this.timeout(30000);
Expand All @@ -20,48 +18,6 @@ describe("fetch-info module", function () {
return { name, url: `https://www.w3.org/TR/${name}/` };
}

describe("W3C API key", () => {
it("is defined otherwise some tests cannot pass", () => {
assert.ok(w3cApiKey);
});
});


describe("fetch from W3C API", () => {
it("works on a TR spec", async () => {
const spec = getW3CSpec("hr-time-2");
const info = await fetchInfo([spec], { w3cApiKey });
assert.ok(info[spec.name]);
assert.equal(info[spec.name].source, "w3c");
assert.equal(info[spec.name].trUrl, spec.url);
assert.equal(info[spec.name].edUrl, "https://w3c.github.io/hr-time/");
assert.equal(info[spec.name].title, "High Resolution Time Level 2");
});

it("can operate on multiple specs at once", async () => {
const spec = getW3CSpec("hr-time-2");
const other = getW3CSpec("presentation-api");
const info = await fetchInfo([spec, other], { w3cApiKey });
assert.ok(info[spec.name]);
assert.equal(info[spec.name].source, "w3c");
assert.equal(info[spec.name].trUrl, spec.url);
assert.equal(info[spec.name].edUrl, "https://w3c.github.io/hr-time/");
assert.equal(info[spec.name].title, "High Resolution Time Level 2");

assert.ok(info[other.name]);
assert.equal(info[other.name].source, "w3c");
assert.equal(info[other.name].trUrl, other.url);
assert.equal(info[other.name].edUrl, "https://w3c.github.io/presentation-api/");
assert.equal(info[other.name].title, "Presentation API");
});

it("throws when W3C API key is invalid", async () => {
assert.rejects(
fetchInfo([getW3CSpec("selectors-3")], { w3cApiKey: "invalid" }),
/^W3C API returned an error, status code is 403$/);
});
});


describe("fetch from Specref", () => {
it("works on a TR spec in the absence of W3C API key", async () => {
Expand All @@ -78,7 +34,7 @@ describe("fetch-info module", function () {
url: "https://dom.spec.whatwg.org/",
name: "dom"
};
const info = await fetchInfo([spec], { w3cApiKey });
const info = await fetchInfo([spec]);
assert.ok(info[spec.name]);
assert.equal(info[spec.name].source, "specref");
assert.equal(info[spec.name].edUrl, "https://dom.spec.whatwg.org/");
Expand Down Expand Up @@ -129,40 +85,9 @@ describe("fetch-info module", function () {
});


describe("fetch from all sources", () => {
it("merges info from sources", async () => {
const w3c = getW3CSpec("presentation-api");
const whatwg = {
url: "https://html.spec.whatwg.org/multipage/",
name: "html"
};
const other = {
url: "https://tabatkins.github.io/bikeshed/",
name: "bikeshed"
};
const info = await fetchInfo([w3c, whatwg, other], { w3cApiKey });
assert.ok(info[w3c.name]);
assert.equal(info[w3c.name].source, "w3c");
assert.equal(info[w3c.name].trUrl, w3c.url);
assert.equal(info[w3c.name].edUrl, "https://w3c.github.io/presentation-api/");
assert.equal(info[w3c.name].title, "Presentation API");

assert.ok(info[whatwg.name]);
assert.equal(info[whatwg.name].source, "specref");
assert.equal(info[whatwg.name].edUrl, whatwg.url);
assert.equal(info[whatwg.name].title, "HTML Standard");

assert.ok(info[other.name]);
assert.equal(info[other.name].source, "spec");
assert.equal(info[other.name].edUrl, other.url);
assert.equal(info[other.name].title, "Bikeshed Documentation");
});
});


describe("specs-info.json file", () => {
const schema = require("../schema/specs-info.json");
const dfnsSchema = require("../schema/dfns.json");
const dfnsSchema = require("../schema/definitions.json");
const info = require("../specs-info.json");
const Ajv = require("ajv");
const ajv = new Ajv();
Expand Down
2 changes: 1 addition & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const assert = require("assert");
const source = require("../specs.json");
const { specs } = require("../index.js");
const schema = require("../schema/index.json");
const dfnsSchema = require("../schema/dfns.json");
const dfnsSchema = require("../schema/definitions.json");
const Ajv = require("ajv");
const ajv = new Ajv();

Expand Down