From 4b95136a7e8e5c76cc4842b3ab6ffd1a6568af3a Mon Sep 17 00:00:00 2001 From: daisuke Date: Fri, 26 Jul 2019 13:46:46 +0900 Subject: [PATCH] Support html element issue in webcompat library --- data/build.js | 1 + extension/lib/tests/html-element.test.js | 95 ++++++++++++++++++++++++ extension/lib/webcompat.js | 73 ++++++++++++------ 3 files changed, 145 insertions(+), 24 deletions(-) create mode 100644 extension/lib/tests/html-element.test.js diff --git a/data/build.js b/data/build.js index 6bad873..6efbe5c 100644 --- a/data/build.js +++ b/data/build.js @@ -7,6 +7,7 @@ const path = require("path") const payload = { browsers: compatData.browsers, css: compatData.css, + html: compatData.html, } const content = `export default ${ JSON.stringify(payload) };` diff --git a/extension/lib/tests/html-element.test.js b/extension/lib/tests/html-element.test.js new file mode 100644 index 0000000..7178eea --- /dev/null +++ b/extension/lib/tests/html-element.test.js @@ -0,0 +1,95 @@ +"use strict"; + +import { WebCompat } from "../webcompat"; +import webCompatData from "../../webcompat-data.js"; +const webcompat = new WebCompat(webCompatData); + +const FIREFOX_69 = { + id: "firefox", + version: "69", +}; + +const FIREFOX_1 = { + id: "firefox", + version: "1", +}; + +test("a supported html element", () => { + const elementName = "body"; + const issue = webcompat.getHTMLElementIssue(elementName, [FIREFOX_69]); + expect(issue).toBeNull(); +}); + +test("a non supported html element", () => { + const elementName = "main"; + const issue = webcompat.getHTMLElementIssue(elementName, [FIREFOX_69, FIREFOX_1]); + expect(issue).not.toBeNull(); + + const expectedIssue = { + type: WebCompat.ISSUE_TYPE.HTML_ELEMENT, + element: elementName, + unsupportedBrowsers: [FIREFOX_1], + }; + assertIssue(issue, expectedIssue); +}); + +test("an experimental html element", () => { + const elementName = "menu"; + const issue = webcompat.getHTMLElementIssue(elementName, [FIREFOX_69]); + expect(issue).not.toBeNull(); + + const expectedIssue = { + type: WebCompat.ISSUE_TYPE.HTML_ELEMENT, + element: elementName, + experimental: true, + unsupportedBrowsers: [], + }; + assertIssue(issue, expectedIssue); +}); + +test("a deprecated html element", () => { + const elementName = "frame"; + const issue = webcompat.getHTMLElementIssue(elementName, [FIREFOX_69]); + expect(issue).not.toBeNull(); + + const expectedIssue = { + type: WebCompat.ISSUE_TYPE.HTML_ELEMENT, + element: elementName, + deprecated: true, + unsupportedBrowsers: [], + }; + assertIssue(issue, expectedIssue); +}); + +test("an invalid html element", () => { + const elementName = "invalid"; + const issue = webcompat.getHTMLElementIssue(elementName, [FIREFOX_69]); + expect(issue).not.toBeNull(); + + const expectedIssue = { + type: WebCompat.ISSUE_TYPE.HTML_ELEMENT, + element: elementName, + invalid: true, + unsupportedBrowsers: [], + }; + assertIssue(issue, expectedIssue); +}); + +function assertIssue(actualIssue, expectedIssue) { + expect(actualIssue.type).toBe(expectedIssue.type); + expect(actualIssue.element).toBe(expectedIssue.element); + expect(!!actualIssue.invalid).toBe(!!expectedIssue.invalid); + expect(!!actualIssue.deprecated).toBe(!!expectedIssue.deprecated); + expect(!!actualIssue.experimental).toBe(!!expectedIssue.experimental); + expect(!!actualIssue.unsupportedBrowsers).toBe(!!expectedIssue.unsupportedBrowsers); + + if (actualIssue.unsupportedBrowsers) { + const actualUnsupportedBrowsers = actualIssue.unsupportedBrowsers; + const expectedUnsupportedBrowsers = expectedIssue.unsupportedBrowsers; + expect(actualUnsupportedBrowsers.length).toBe(expectedUnsupportedBrowsers.length); + + for (let i = 0; i < actualUnsupportedBrowsers.length; i++) { + expect(actualUnsupportedBrowsers[i]).toBe(expectedUnsupportedBrowsers[i]); + } + } +} diff --git a/extension/lib/webcompat.js b/extension/lib/webcompat.js index eb098fd..7dcb15c 100644 --- a/extension/lib/webcompat.js +++ b/extension/lib/webcompat.js @@ -14,6 +14,7 @@ const _ISSUE_TYPE = { CSS_PROPERTY_ALIASES: "CSS_PROPERTY_ALIASES", CSS_VALUE: "CSS_VALUE", CSS_VALUE_ALIASES: "CSS_VALUE_ALIASES", + HTML_ELEMENT: "HTML_ELEMENT", }; // The follwing data will not be necessary if this issue is fixed. @@ -81,6 +82,25 @@ class WebCompat { return this._toCSSIssues(normalSummaries.concat(aliasSummaries)); } + /** + * @param {String} elementName - + * e.g. div, main, aside + * @param {Array} browsers - + * e.g. [{ id: "firefox", name: "Firefox", version: "68" }, ...] + * @return {Object} if no issue found, return null. + */ + getHTMLElementIssue(elementName, browsers) { + const database = this._webCompatData.html.elements; + const summary = this._getCompatSummary(browsers, database, elementName); + + if (!this._hasIssue(summary)) { + return null; + } + + summary.element = elementName; + return this._toIssue(summary, _ISSUE_TYPE.HTML_ELEMENT); + } + _asFloatVersion(version = false) { if (version === true) { return 0; @@ -93,8 +113,6 @@ class WebCompat { const aliasSummariesMap = new Map(); const normalSummaries = summaries.filter(s => { const { database, invalid, property, terms, unsupportedBrowsers, value } = s; - delete s.database; - delete s.terms; if (invalid) { return true; @@ -416,6 +434,10 @@ class WebCompat { return compatTable ? compatTable.status : {}; } + _hasIssue({ unsupportedBrowsers, deprecated, experimental, invalid }) { + return unsupportedBrowsers.length || deprecated || experimental || invalid; + } + _hasTerm(compatNode, ...terms) { return !!this._getCompatTable(compatNode, terms); } @@ -436,30 +458,33 @@ class WebCompat { }); } + _toIssue(summary, type) { + return Object.assign({}, summary, { type, database: undefined, terms: undefined }); + } + _toCSSIssues(summaries) { - return summaries - // Filter only what the summary has problem. - .filter(s => s.unsupportedBrowsers.length || - s.deprecated || - s.experimental || - s.invalid) - // Finally, classify the issue type. - .map(issue => { - let type = null; - - if (issue.aliases) { - type = typeof issue.value !== "undefined" - ? _ISSUE_TYPE.CSS_VALUE_ALIASES - : _ISSUE_TYPE.CSS_PROPERTY_ALIASES; - } else { - type = typeof issue.value !== "undefined" - ? _ISSUE_TYPE.CSS_VALUE - : _ISSUE_TYPE.CSS_PROPERTY; - } + const issues = []; + + for (const summary of summaries) { + if (!this._hasIssue(summary)) { + continue; + } + + let type = null; + if (summary.aliases) { + type = typeof summary.value !== "undefined" + ? _ISSUE_TYPE.CSS_VALUE_ALIASES + : _ISSUE_TYPE.CSS_PROPERTY_ALIASES; + } else { + type = typeof summary.value !== "undefined" + ? _ISSUE_TYPE.CSS_VALUE + : _ISSUE_TYPE.CSS_PROPERTY; + } + + issues.push(this._toIssue(summary, type)); + } - issue.type = type; - return issue; - }); + return issues; } }