From d24c244cbb00d310c400a6fd3e830a8e2b36b908 Mon Sep 17 00:00:00 2001 From: Marcos Caceres Date: Sat, 5 Mar 2016 01:23:40 +1100 Subject: [PATCH] Feat (biblio.js): don't go to network for local refs --- js/core/biblio.js | 99 +++++++++++++++++----------- karma.conf.js | 6 +- tests/spec/core/biblio-spec.js | 35 ++++++++-- tests/spec/core/inlines-spec.js | 12 +++- tests/spec/w3c/local-aliases-spec.js | 7 +- tests/test-main.js | 8 ++- 6 files changed, 118 insertions(+), 49 deletions(-) diff --git a/js/core/biblio.js b/js/core/biblio.js index 195e997a93..ffee510a1d 100644 --- a/js/core/biblio.js +++ b/js/core/biblio.js @@ -1,9 +1,12 @@ - // Module core/biblio // Handles bibliographic references // Configuration: // - localBiblio: override or supplement the official biblio with your own. +/*jshint jquery: true*/ +/*globals console*/ +"use strict"; + define( [], function () { @@ -80,7 +83,7 @@ define( var $sec = $("

") .appendTo($refsec) .find("h3") - .text(type + " references") + .text(type + " references") .end() ; $sec.makeID(null, type + " references"); @@ -138,46 +141,66 @@ define( return { stringifyRef: stringifyRef, - run: function (conf, doc, cb, msg) { + run: function (conf, doc, cb, msg) { + function finish() { + msg.pub("end", "core/biblio"); + cb(); + } msg.pub("start", "core/biblio"); - var refs = getRefKeys(conf) - , localAliases = [] - , finish = function () { - msg.pub("end", "core/biblio"); - cb(); - } - ; - if (conf.localBiblio) { - for (var k in conf.localBiblio) { - if (typeof conf.localBiblio[k].aliasOf !== "undefined") { - localAliases.push(conf.localBiblio[k].aliasOf); - } - } + if(!conf.localBiblio){ + conf.localBiblio = {}; } - refs = refs.normativeReferences - .concat(refs.informativeReferences) - .concat(localAliases); - if (refs.length) { - var url = "https://labs.w3.org/specrefs/bibrefs?refs=" + refs.join(","); - $.ajax({ - dataType: "json" - , url: url - , success: function (data) { - conf.biblio = data || {}; - // override biblio data - if (conf.localBiblio) { - for (var k in conf.localBiblio) conf.biblio[k] = conf.localBiblio[k]; - } - bibref(conf, msg); - finish(); - } - , error: function (xhr, status, error) { - msg.pub("error", "Error loading references from '" + url + "': " + status + " (" + error + ")"); - finish(); - } + if(conf.biblio){ + var warn = "Overriding `.biblio` in config. Please use `.localBiblio` for custom biblio entries."; + msg.pub("warn", warn); + } + conf.biblio = {}; + var localAliases = Array + .from(Object.keys(conf.localBiblio)) + .filter(function(key){ + return conf.localBiblio[key].hasOwnProperty("aliasOf"); + }) + .map(function(key){ + return conf.localBiblio[key].aliasOf; }); + + var allRefs = getRefKeys(conf); + var externalRefs = allRefs.normativeReferences + .concat(allRefs.informativeReferences) + // Filter, as to not go to network for local refs + .filter(function(key){ + return !conf.localBiblio.hasOwnProperty(key); + }) + // but include local aliases, in case they refer to external specs + .concat(localAliases) + // remove duplicates + .reduce(function(collector, item){ + if(!collector.includes(item)){ + collector.push(item); + } + return collector; + }, []) + .sort(); + // If we don't need to go to network, just use internal biblio + if (!externalRefs.length) { + Object.assign(conf.biblio, conf.localBiblio); + bibref(conf, msg); + finish(); + return; } - else finish(); + var url = "https://labs.w3.org/specrefs/bibrefs?refs=" + externalRefs.join(","); + fetch(url) + .then(function(response) { + return response.json(); + }) + .then(function(data) { + Object.assign(conf.biblio, data, conf.localBiblio); + bibref(conf, msg); + }) + .catch(function(err) { + console.error(err); + }) + .then(finish); } }; } diff --git a/karma.conf.js b/karma.conf.js index 86fe5518c4..3c8c5071c9 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -64,7 +64,11 @@ module.exports = function(config) { included: false, served: true, }, { - pattern: "node_modules/webidl2/lib/*.js", + pattern: "./node_modules/webidl2/lib/*.js", + included: false, + served: true, + },{ + pattern: "./node_modules/whatwg-fetch/fetch.js", included: false, served: true, }, diff --git a/tests/spec/core/biblio-spec.js b/tests/spec/core/biblio-spec.js index c3eb580016..7bf24b3401 100644 --- a/tests/spec/core/biblio-spec.js +++ b/tests/spec/core/biblio-spec.js @@ -1,13 +1,33 @@ "use strict"; describe("W3C — Bibliographic References", function() { + var isSpecRefAvailable = true; + afterAll(function(done) { flushIframes(); done(); }); + + // Ping biblio service to see if it's running + it("should reach biblio service", function(done) { + var fetchOps = { + method: "HEAD" + }; + fetch("https://labs.w3.org/specrefs/bibrefs", fetchOps) + .then(function(res) { + isSpecRefAvailable = res.ok; + expect(res.ok).toBeTruthy(); + done(); + }) + .catch(function(err) { + fail("Error", err); + done(); + }); + }); + var customConfig = { - editors: [ - {name: "Robin Berjon"} - ], + editors: [{ + name: "Robin Berjon" + }], shortName: "Foo", specStatus: "WD", prevVersion: "FPWD", @@ -43,6 +63,11 @@ describe("W3C — Bibliographic References", function() { // Make sure the reference is added. var ref = doc.querySelector("#bib-TestRef1 + dd"); expect(ref).toBeTruthy(); + // This prevents Jasmine from taking down the whole test suite if SpecRef is down. + if (!isSpecRefAvailable) { + var err = new Error("SpecRef seems to be down. Can't proceed with this spec."); + return Promise.reject(err); + } expect(ref.textContent).toMatch(/Publishers Inc\.\s/); ref = null; // Make sure the ". " is automatically added to publisher. @@ -55,6 +80,6 @@ describe("W3C — Bibliographic References", function() { ref = doc.querySelector("#bib-TestRef3 + dd"); expect(ref).toBeTruthy(); expect(ref.textContent).toMatch(/^Publisher Here\.\s/); - }).then(done); + }).then(done).catch(done); }); -}); +}); \ No newline at end of file diff --git a/tests/spec/core/inlines-spec.js b/tests/spec/core/inlines-spec.js index 4ae98367bb..2d1102bea5 100644 --- a/tests/spec/core/inlines-spec.js +++ b/tests/spec/core/inlines-spec.js @@ -4,7 +4,7 @@ describe("Core - Inlines", function() { flushIframes(); done(); }); - it("should process all inline content", function(done) { + it("should process all in-line content", function(done) { var ops = { config: makeBasicConfig(), body: makeDefaultBody() + @@ -15,6 +15,16 @@ describe("Core - Inlines", function() { "

[[!DAHU]] [[REX]]

" + "", }; + ops.config.localBiblio = { + "DAHU": { + title: "One short leg. How I learned to overcome.", + publisher: "Publishers Inc." + }, + "REX": { + title: "Am I a dinosaur or a failed technology?", + publisher: "Publishers Inc." + }, + }; makeRSDoc(ops, function(doc) { var $inl = $("#inlines", doc); var $nr = $("#normative-references", doc); diff --git a/tests/spec/w3c/local-aliases-spec.js b/tests/spec/w3c/local-aliases-spec.js index ea99fd206a..b51916766d 100644 --- a/tests/spec/w3c/local-aliases-spec.js +++ b/tests/spec/w3c/local-aliases-spec.js @@ -12,13 +12,16 @@ describe("W3C — Aliased References", function() { }; ops.config.localBiblio = { "FOOBARGLOP": { - "aliasOf": "RFC2119" + "aliasOf": "BARBAR", + }, + "BARBAR": { + title: "The BARBAR Spec", } }; makeRSDoc(ops, function(doc) { var $r = $("#bib-FOOBARGLOP + dd", doc); expect($r.length).toBeTruthy(); - expect($r.text()).toMatch(/2119/); + expect($r.text()).toMatch(/BARBAR/); }).then(done); }); }); diff --git a/tests/test-main.js b/tests/test-main.js index 6959880399..5992ccda02 100644 --- a/tests/test-main.js +++ b/tests/test-main.js @@ -17,7 +17,10 @@ var testFiles = Object.keys(window.__karma__.files) return collector; }, []); -var allDeps = ["js/core/jquery-enhanced"].concat(testFiles); +var allDeps = [ + "js/core/jquery-enhanced", + "fetch", +].concat(testFiles); require.config({ // Karma serves files under /base, which is the basePath from your config file @@ -26,8 +29,9 @@ require.config({ "jquery": "/base/node_modules/jquery/dist/jquery", "core/utils": "js/core/utils", "core/jquery-enhanced": "js/core/jquery-enhanced", + "fetch": "/base/node_modules/whatwg-fetch/fetch" }, - // dynamically load all test files + // dynamically load all test files and other deps deps: allDeps, // we have to kickoff jasmine, as it is asynchronous callback: window.__karma__.start,