From 7324b09d4083438863b791f2c490a922b836a323 Mon Sep 17 00:00:00 2001 From: jkodu Date: Wed, 12 Jun 2019 15:12:57 +0100 Subject: [PATCH 01/20] generate implementation --- build/get-implementations-data.js | 42 +++++++++++ build/get-implementations.js | 70 ------------------- build/get-wcag-sc-metadata.js | 2 +- build/implementations/get-assertion-source.js | 24 +++++++ build/implementations/get-assertions.js | 17 +++++ .../get-best-matching-rules.js | 20 ++++++ build/implementations/get-framed-report.js | 61 ++++++++++++++++ build/implementations/get-implementation.js | 26 +++++++ .../implementations/get-rule-mapping-state.js | 48 +++++++++++++ build/implementations/get-rule-mapping.js | 53 ++++++++++++++ .../get-testcase-assertions.js | 27 +++++++ build/implementations/get-testcase-mapping.js | 38 ++++++++++ .../get-testcase-relative-url.js | 13 ++++ .../get-testcases-grouped-by-rule.js | 23 ++++++ .../json-ld-frame-config.js} | 0 gatsby/create-glossary-uages-in-rules.js | 2 +- gatsby/create-testcases-json.js | 2 +- gatsby/create-testcases-of-all-rules.js | 5 +- ...ate-testcases-of-rule-of-em-report-tool.js | 2 +- package-lock.json | 13 ++++ package.json | 52 +++++++++++--- pages/implementations/testcases.md | 6 +- {build => utils}/create-file.js | 0 23 files changed, 458 insertions(+), 88 deletions(-) create mode 100644 build/get-implementations-data.js delete mode 100644 build/get-implementations.js create mode 100644 build/implementations/get-assertion-source.js create mode 100644 build/implementations/get-assertions.js create mode 100644 build/implementations/get-best-matching-rules.js create mode 100644 build/implementations/get-framed-report.js create mode 100644 build/implementations/get-implementation.js create mode 100644 build/implementations/get-rule-mapping-state.js create mode 100644 build/implementations/get-rule-mapping.js create mode 100644 build/implementations/get-testcase-assertions.js create mode 100644 build/implementations/get-testcase-mapping.js create mode 100644 build/implementations/get-testcase-relative-url.js create mode 100644 build/implementations/get-testcases-grouped-by-rule.js rename build/{implementation-json-ld-frame.js => implementations/json-ld-frame-config.js} (100%) rename {build => utils}/create-file.js (100%) diff --git a/build/get-implementations-data.js b/build/get-implementations-data.js new file mode 100644 index 0000000000..67f871d283 --- /dev/null +++ b/build/get-implementations-data.js @@ -0,0 +1,42 @@ +const { config: { implementations } } = require('./../package.json') +const getFramedReport = require('./implementations/get-framed-report') +const getImplementation = require('./implementations/get-implementation') +const createFile = require('./../utils/create-file') + +/** + * Create implementation metrics, that can be used in the site, + * for each `implementation` provided as configuration in `package.json`. + */ +const init = async () => { + if (!implementations || !Object.keys(implementations).length) { + throw new Error('No implementations are specified in `config` of `package.json`') + } + + for (let item of implementations) { + const { provider, tool, data } = item + + console.info(`Get implementation data of ${tool} by ${provider}\n`) + + /** + * fetch report & frame as required + */ + const framedReport = await getFramedReport(data) + + /** + * get implementation metrics from report + */ + const implementation = await getImplementation(framedReport) + + await createFile( + `public/implementations/${tool}.json`, + JSON.stringify(implementation, null, 2) + ) + } +} + +init() + .then(() => console.info(`Implementations data generated.`)) + .catch(err => { + console.error(err); + process.exit(1) + }) \ No newline at end of file diff --git a/build/get-implementations.js b/build/get-implementations.js deleted file mode 100644 index cabe1fb11b..0000000000 --- a/build/get-implementations.js +++ /dev/null @@ -1,70 +0,0 @@ -const path = require('path') -const axios = require('axios') -const jsonld = require('jsonld') -const pkg = require('./../package.json') -const jsonLdFrameConfig = require('./implementation-json-ld-frame') -const createFile = require('./create-file') -const outputFile = path.join(__dirname, '..', '_data', 'implementations.json') - -/** - * Transform data to JSONLD frame - * @param {Object} data data - * @param {String} reportUrl url - */ -const getFramedResult = async (data, url) => { - return new Promise((resolve, reject) => { - jsonld.frame(data, jsonLdFrameConfig, (err, result) => { - if (err) { - reject(err) - } - result['reportUrl'] = url - resolve(result) - }) - }) -} - -/** - * Given report data - * - * @param {String} url resource endpoint for the report - */ -const getReportData = url => { - return axios.get(url).then(async response => { - const { data } = response - return await getFramedResult(data, url) - }) -} - -/** - * Tabulate implementation data - * @param {Array} data - */ -const tabulateImplementationData = data => { - return data.map(implementation => { - const graph = implementation['@graph'] - if (!graph || !graph.length) { - return - } - const assertedBy = graph[0]['assertedBy'] - return { - vendorName: assertedBy['vendor']['foaf:name'], - vendorTool: assertedBy['vendorTool'], - vendorToolVersion: assertedBy['@id'].split('/').reverse()[0], - reportUrl: implementation.reportUrl, - } - }) -} - -;(async () => { - const implementations = pkg.config.implementations - if (!implementations || Object.keys(implementations).length <= 0) { - throw new Error('No implementations are specified in config.') - } - - const reports = Object.values(implementations) - const promises = reports.map(getReportData) - const result = await Promise.all(promises) - const tabulatedData = tabulateImplementationData(result) - createFile(outputFile, JSON.stringify(tabulatedData, undefined, 2)) - console.info('\nDONE!!! Generated Implementations Data.\n') -})() diff --git a/build/get-wcag-sc-metadata.js b/build/get-wcag-sc-metadata.js index 3f4cd7aed7..9b90b16cbc 100644 --- a/build/get-wcag-sc-metadata.js +++ b/build/get-wcag-sc-metadata.js @@ -5,7 +5,7 @@ */ const path = require('path') const axios = require('axios') -const createFile = require('./create-file') +const createFile = require('./../utils/create-file') const pkg = require('./../package.json') const outputFileScMetaData = path.join(__dirname, '..', '_data', 'sc-urls.json') const outputFileScEmReportAuditResult = path.join( diff --git a/build/implementations/get-assertion-source.js b/build/implementations/get-assertion-source.js new file mode 100644 index 0000000000..13b6dde312 --- /dev/null +++ b/build/implementations/get-assertion-source.js @@ -0,0 +1,24 @@ +const flat = require('flat') +const isUrl = require('is-url') +const { www: { url: siteUrl } } = require('./../../package.json') + +/** + * Given an assertion object + * - get `source`, which resembles closest to the url of the testcase + * + * Achieved by + * - flatten the given object + * - and verity if values are of type `url` and has `siteUrl` + * @param {Object} assertion assertion + */ +const getAssertionSource = assertion => { + const flattenedAssertion = flat(assertion); + return Object.values(flattenedAssertion).find(value => { + return ( + isUrl(value) && + value.includes(siteUrl) + ) + }) +} + +module.exports = getAssertionSource \ No newline at end of file diff --git a/build/implementations/get-assertions.js b/build/implementations/get-assertions.js new file mode 100644 index 0000000000..297c486834 --- /dev/null +++ b/build/implementations/get-assertions.js @@ -0,0 +1,17 @@ +/** + * Get assertions from framed reports + * + * @param {Object|Array} framedReports implementation reports + */ +const getAssertions = framedReports => { + const reports = Array.isArray(framedReports) + ? framedReports + : [framedReports] + + return reports.reduce((out, report) => { + out.push(...report[`@graph`]) + return out + }, []) +} + +module.exports = getAssertions; \ No newline at end of file diff --git a/build/implementations/get-best-matching-rules.js b/build/implementations/get-best-matching-rules.js new file mode 100644 index 0000000000..cf1baeff82 --- /dev/null +++ b/build/implementations/get-best-matching-rules.js @@ -0,0 +1,20 @@ +/** + * Given a set of assertion results, get best fit, based on outcome mapping + * + * @param {Array} ruleAsserts mapped assertions + */ +const getBestMatchingRules = ruleAsserts => { + const mappedRules = ruleAsserts.filter(({ mapping }) => mapping !== false) + if (!mappedRules) { + return + } + + const completeRules = mappedRules.filter(({ complete }) => complete === true) + if (!completeRules) { + return mappedRules; + } + + return completeRules; +} + +module.exports = getBestMatchingRules \ No newline at end of file diff --git a/build/implementations/get-framed-report.js b/build/implementations/get-framed-report.js new file mode 100644 index 0000000000..49616810b2 --- /dev/null +++ b/build/implementations/get-framed-report.js @@ -0,0 +1,61 @@ +const fs = require('fs') +const globby = require('globby') +const axios = require('axios') +const jsonld = require('jsonld') +const { exec } = require('child_process') +const frameConfig = require('./json-ld-frame-config') + + +const getFramedReport = async options => { + const { type } = options; + + if (![`NPM`, `JSON`].includes(type)) { + throw new Error('Provided type ${type} for report is not val`') + } + + if (type === `JSON`) { + const { path: url } = options; + const { data } = await axios.get(url); + return await jsonld.frame(data, frameConfig) + } + + if (type === `NPM`) { + const { exec: command, path } = options; + + // `npm i module` + await executeCommand(command) + + const reports = globby.sync([`./node_modules/${path}`]) + .map(reportPath => { + const fileContent = fs.readFileSync(reportPath, { encoding: 'utf-8' }) + return JSON.parse(fileContent) + }) + + const result = [] + + for (let report of reports) { + const framedReport = await jsonld.frame(report, frameConfig) + result.push(framedReport) + } + + return result; + } +} + +module.exports = getFramedReport + + +/** + * Execute a given command + * + * @param {String} command command to execute + */ +async function executeCommand(command) { + return new Promise((resolve, reject) => + exec(command, (err, result) => { + if (err) { + reject(err) + } + resolve(result) + })) +} \ No newline at end of file diff --git a/build/implementations/get-implementation.js b/build/implementations/get-implementation.js new file mode 100644 index 0000000000..f7d24a598c --- /dev/null +++ b/build/implementations/get-implementation.js @@ -0,0 +1,26 @@ +const getAssertions = require('./get-assertions') +const getTestcasesGroupedByRule = require('./get-testcases-grouped-by-rule') +const getRuleMapping = require('./get-rule-mapping') + +/** + * Get implementation metric from submitted report + * + * @param {Object|Array} framedReports implementation reports + */ +const getImplementation = async framedReports => { + const assertions = getAssertions(framedReports) + const testcasesGroupedByRuleId = await getTestcasesGroupedByRule() + + return Object.keys(testcasesGroupedByRuleId) + .map(ruleId => { + const ruleTestcases = testcasesGroupedByRuleId[ruleId] + const implementation = getRuleMapping(ruleTestcases, assertions) + return { + ruleId, + implementation + } + }) + .filter(result => (result.implementation && result.implementation.length > 0)) +} + +module.exports = getImplementation \ No newline at end of file diff --git a/build/implementations/get-rule-mapping-state.js b/build/implementations/get-rule-mapping-state.js new file mode 100644 index 0000000000..cb44243ecb --- /dev/null +++ b/build/implementations/get-rule-mapping-state.js @@ -0,0 +1,48 @@ +const assert = require('assert') + +const outcomeMapping = { + failed: ['failed', 'cantTell'], + fail: ['failed', 'cantTell'], + passed: ['passed', 'cantTell', 'inapplicable'], + pass: ['passed', 'cantTell', 'inapplicable'], + inapplicable: ['passed', 'cantTell', 'inapplicable', 'untested'], +} + +/** + * Get rule state based on given assertions + * + * @param {Array} assertions + */ +const getRuleMappingState = assertions => { + const mapping = assertions.some(({ actual, expected }) => + expected === 'failed' && ['failed', 'cantTell'].includes(actual)) + + if (!mapping) { + return { mapping: false }; + } + + const complete = assertions.every(({ expected, actual }) => { + return expected !== 'failed' || actual === 'failed' + }) + + const incorrect = assertions + .filter((data) => { + const { expected, actual } = data + assert(outcomeMapping[expected], `Unknown result type ${expected}`) + + return !outcomeMapping[expected].includes(actual) + }) + .map(({ url }) => url) + + // const fullAuto = undefined + + return { + complete, + incorrect, + assertions: assertions.map(({ expected, actual, url }) => { + return { expected, actual, url } + }) + } +} + +module.exports = getRuleMappingState \ No newline at end of file diff --git a/build/implementations/get-rule-mapping.js b/build/implementations/get-rule-mapping.js new file mode 100644 index 0000000000..b6e2c9e12f --- /dev/null +++ b/build/implementations/get-rule-mapping.js @@ -0,0 +1,53 @@ +const getTestcaseRelativeUrl = require('./get-testcase-relative-url') +const getRuleMappingState = require('./get-rule-mapping-state') +const getBestMatchingRules = require('./get-best-matching-rules') +const getTestcaseAssertions = require('./get-testcase-assertions') +const getTestCaseMapping = require('./get-testcase-mapping') + +function getRuleMapping(testcases, assertions) { + const ruleData = {} + + testcases.forEach(tc => { + const relativeUrl = getTestcaseRelativeUrl(tc.url) + const tcAssertions = getTestcaseAssertions(assertions, relativeUrl) + + // Create a mapping for each assertion + tcAssertions.forEach(assertion => { + const testMapping = getTestCaseMapping(assertion, tc) + if (!testMapping || testMapping.actual === 'untested') { + return + } + if (!ruleData[testMapping.title]) { + ruleData[testMapping.title] = [] + } + ruleData[testMapping.title].push(testMapping) + }) + }) + + for (tc of testcases) { + const relativeUrl = getTestcaseRelativeUrl(tc.url) + + // Push untested results for every test case without an assertion + Object.values(ruleData).forEach(testMappings => { + if (!testMappings.some(({ url }) => url && url.includes(relativeUrl))) { + testMappings.push({ + title: testMappings[0].title, + expected: tc.expected, + actual: 'untested', + url: tc.url + }) + } + }) + } + + const ruleAsserts = Object.values(ruleData).map(data => { + const mappingState = getRuleMappingState(data) + return { + ...mappingState + } + }) + + return getBestMatchingRules(ruleAsserts) +} + +module.exports = getRuleMapping; \ No newline at end of file diff --git a/build/implementations/get-testcase-assertions.js b/build/implementations/get-testcase-assertions.js new file mode 100644 index 0000000000..adeda8e3c6 --- /dev/null +++ b/build/implementations/get-testcase-assertions.js @@ -0,0 +1,27 @@ +const getAssertionSource = require('./get-assertion-source') + +/** + * Get all assertions for given testcase + * Note: cache assertion for easier look-up + * + * @param {Array} assertions assertions + * @param {String} relativeUrl relative url of testcase + */ +const getTestcaseAssertions = (assertions, relativeUrl) => { + var cache = {} + + const cacheKeys = Object.keys(cache); + if (cacheKeys.includes(relativeUrl)) { + return cache[relativeUrl] + } + + const testcaseAssertions = assertions.filter(assertion => { + const source = getAssertionSource(assertion) + return source.includes(relativeUrl) + }) + + cache[relativeUrl] = testcaseAssertions; + return testcaseAssertions; +} + +module.exports = getTestcaseAssertions \ No newline at end of file diff --git a/build/implementations/get-testcase-mapping.js b/build/implementations/get-testcase-mapping.js new file mode 100644 index 0000000000..8289a736a8 --- /dev/null +++ b/build/implementations/get-testcase-mapping.js @@ -0,0 +1,38 @@ +const getAssertionSource = require('./get-assertion-source') + +/** + * Utility fn to get title from assertion + * + * @param {Object} assertion assertion + * @returns {String} + */ +const getTitleFromAssertion = assertion => { + const { test, EMTest } = assertion + if (!test) { + return EMTest || null + } + if (typeof test === 'string') { + return test + } + if (test.title) { + return test.title + } + return test['@id'] || '' +} + +/** + * Get mapping for a given testcase + * + * @param {Object} assertion assertion + * @param {Object} tc testcase + */ +const getTestcaseMapping = (assertion, { expected }) => { + return { + title: getTitleFromAssertion(assertion), + url: getAssertionSource(assertion), + expected: expected, + actual: assertion.result.outcome.replace('earl:', '') + } +} + +module.exports = getTestcaseMapping \ No newline at end of file diff --git a/build/implementations/get-testcase-relative-url.js b/build/implementations/get-testcase-relative-url.js new file mode 100644 index 0000000000..d23194d3c7 --- /dev/null +++ b/build/implementations/get-testcase-relative-url.js @@ -0,0 +1,13 @@ +const { www: { url: siteUrl } } = require('./../../package.json') + +/** + * Get relative (suffix) from url + * + * @param {String} url url + */ +const getTestcaseRelativeUrl = url => { + const urlPrefix = `${siteUrl}/testcases/` + return url.substr(url.indexOf(urlPrefix)) +} + +module.exports = getTestcaseRelativeUrl \ No newline at end of file diff --git a/build/implementations/get-testcases-grouped-by-rule.js b/build/implementations/get-testcases-grouped-by-rule.js new file mode 100644 index 0000000000..d010c49c1b --- /dev/null +++ b/build/implementations/get-testcases-grouped-by-rule.js @@ -0,0 +1,23 @@ +const axios = require('axios') +const { config } = require('./../../package.json') + +/** + * Get testcases of rules + * - group them by `ruleId` + */ +const getTestcasesGroupedByRule = async () => { + const testcasesUrl = config['testcases-url'] + const { data } = await axios.get(testcasesUrl) + const { testcases } = data + + return testcases.reduce((out, testcase) => { + const { ruleId } = testcase + if (!out[ruleId]) { + out[ruleId] = [] + } + out[ruleId].push(testcase) + return out + }, {}) +} + +module.exports = getTestcasesGroupedByRule \ No newline at end of file diff --git a/build/implementation-json-ld-frame.js b/build/implementations/json-ld-frame-config.js similarity index 100% rename from build/implementation-json-ld-frame.js rename to build/implementations/json-ld-frame-config.js diff --git a/gatsby/create-glossary-uages-in-rules.js b/gatsby/create-glossary-uages-in-rules.js index 522cc1a09b..b20c7c0ff1 100644 --- a/gatsby/create-glossary-uages-in-rules.js +++ b/gatsby/create-glossary-uages-in-rules.js @@ -5,7 +5,7 @@ */ const queries = require('./queries') const regexps = require('./reg-exps') -const createFile = require('./../build/create-file') +const createFile = require('./../utils/create-file') const getAllMatchesForRegex = require('./get-all-matches-for-regex') const createGlossaryUsagesInRules = options => { diff --git a/gatsby/create-testcases-json.js b/gatsby/create-testcases-json.js index 9bb797bd61..88af3b90fe 100644 --- a/gatsby/create-testcases-json.js +++ b/gatsby/create-testcases-json.js @@ -3,7 +3,7 @@ const { author, description, } = require('./../package.json') -const createFile = require('../build/create-file') +const createFile = require('../utils/create-file') /** * Create `testcases.json` diff --git a/gatsby/create-testcases-of-all-rules.js b/gatsby/create-testcases-of-all-rules.js index f904ab1709..85f1cd5cd0 100644 --- a/gatsby/create-testcases-of-all-rules.js +++ b/gatsby/create-testcases-of-all-rules.js @@ -11,7 +11,7 @@ const fastmatter = require('fastmatter') const { www: { url, baseDir }, } = require('./../package.json') -const createFile = require('../build/create-file') +const createFile = require('../utils/create-file') const getAllMatchesForRegex = require('./get-all-matches-for-regex') const queries = require('./queries') const regexps = require('./reg-exps') @@ -101,8 +101,7 @@ const createTestcasesOfAllRules = options => { ruleId, ruleName, rulePage: `${url}/${slug}`, - ruleAccessibilityRequirements, - requirementsMapping: Object.keys(ruleAccessibilityRequirements || {}), + ruleAccessibilityRequirements } out.push(testcase) diff --git a/gatsby/create-testcases-of-rule-of-em-report-tool.js b/gatsby/create-testcases-of-rule-of-em-report-tool.js index f48b7629b3..64fbe582db 100644 --- a/gatsby/create-testcases-of-rule-of-em-report-tool.js +++ b/gatsby/create-testcases-of-rule-of-em-report-tool.js @@ -6,7 +6,7 @@ const scEmReportAuditResult = require('./../_data/sc-em-report-audit-result.json const graphContext = require('./../_data/wcag-em-report-tool-mappings/@graph-context.json') const graphAdditionalMeta = require('./../_data/wcag-em-report-tool-mappings/@graph-additional-meta.json') const graphEvaluatorMeta = require('./../_data/wcag-em-report-tool-mappings/@graph-evaluator-meta.json') -const createFile = require('./../build/create-file') +const createFile = require('../utils/create-file') /** * Create testcases json file that can be used by diff --git a/package-lock.json b/package-lock.json index 965c132fed..098bae4255 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1641,6 +1641,10 @@ "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", "dev": true }, + "act-rules-implementation-rgaa": { + "version": "https://github.com/act-rules/act-rules-implementation-rgaa/tarball/master", + "integrity": "sha512-5qtUVoNIymuSUl7SH91MTcASE5dfaZQtWte/8HWu7jfTUCt22uPkrRskVgCdbWBLyLqx6bPJR6Zqj662VKi8Xg==" + }, "address": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/address/-/address-1.0.3.tgz", @@ -10046,6 +10050,11 @@ "unc-path-regex": "^0.1.2" } }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" + }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", @@ -17600,6 +17609,10 @@ } } }, + "testrunner": { + "version": "git+https://github.com/act-rules/act-rules-implementation-rgaa.git#1d572a40f6879a75d36090c7275c42e4d0d79cee", + "from": "git+https://github.com/act-rules/act-rules-implementation-rgaa.git" + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", diff --git a/package.json b/package.json index 2f0b1e20ce..83d406ee62 100644 --- a/package.json +++ b/package.json @@ -82,8 +82,10 @@ } ], "dependencies": { + "act-rules-implementation-rgaa": "https://github.com/act-rules/act-rules-implementation-rgaa/tarball/master", "axios": "^0.18.1", "fastmatter": "^2.1.1", + "flat": "^4.1.0", "gatsby": "^2.8.6", "gatsby-image": "^2.1.2", "gatsby-plugin-manifest": "^2.1.1", @@ -93,13 +95,14 @@ "gatsby-plugin-sass": "^2.0.10", "gatsby-plugin-sharp": "^2.1.3", "gatsby-remark-autolink-headers": "^2.0.15", + "gatsby-remark-copy-linked-files": "^2.0.12", "gatsby-remark-prismjs": "^3.2.11", "gatsby-source-filesystem": "^2.0.38", - "gatsby-remark-copy-linked-files": "^2.0.12", "gatsby-transformer-remark": "^2.3.12", "gatsby-transformer-sharp": "^2.1.21", "gfm-code-blocks": "^1.0.0", "globby": "^9.2.0", + "is-url": "^1.2.4", "jsonld": "^1.6.2", "make-dir": "^2.1.0", "marked": "^0.6.2", @@ -112,7 +115,8 @@ "react": "^16.8.6", "react-dom": "^16.8.6", "react-helmet": "^5.2.1", - "showdown": "^1.9.0" + "showdown": "^1.9.0", + "testrunner": "git+https://github.com/act-rules/act-rules-implementation-rgaa" }, "devDependencies": { "husky": "^2.4.0", @@ -138,9 +142,9 @@ "serve": "gatsby serve", "test": "npm run test:rules", "test:rules": "jest", - "get-implementations": "node ./build/get-implementations", + "get-implementations-data": "node ./build/get-implementations-data", "get-wcag-sc-metadata": "node ./build/get-wcag-sc-metadata", - "get-data": "npm run get-wcag-sc-metadata && npm run get-implementations" + "get-data": "npm run get-wcag-sc-metadata && npm run get-implementations-data" }, "homepage": "https://github.com/act-rules/act-rules.github.io", "repository": { @@ -161,10 +165,42 @@ "references": { "wcag21": "https://raw.githubusercontent.com/w3c/wai-wcag-quickref/gh-pages/_data/wcag21.json" }, - "implementations": { - "alfa": "https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json", - "axe": "https://raw.githubusercontent.com/w3c/earl/master/earl-reports/axe-report.json" - }, + "testcases-url": "https://act-rules.github.io/testcases.json", + "implementations": [ + { + "provider": "Level Access", + "tool": "Access Engine", + "data": { + "type": "JSON", + "path": "https://raw.githubusercontent.com/act-rules/act-rules-implementation-access-engine/master/report.json" + } + }, + { + "provider": "Site Improve", + "tool": "Alfa", + "data": { + "type": "JSON", + "path": "https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json" + } + }, + { + "provider": "Deque Systems", + "tool": "Axe", + "data": { + "type": "JSON", + "path": "https://raw.githubusercontent.com/act-rules/act-rules-implementation-axe-core/master/report.json" + } + }, + { + "provider": "Access42", + "tool": "Access42 (RGAA)", + "data": { + "type": "NPM", + "exec": "npm install https://github.com/act-rules/act-rules-implementation-rgaa/tarball/master", + "path": "act-rules-implementation-rgaa/reports/*.json" + } + } + ], "rule-format-metadata": { "input-aspects": { "default": "https://www.w3.org/TR/act-rules-aspects/#intro", diff --git a/pages/implementations/testcases.md b/pages/implementations/testcases.md index 32d5dc00c0..11656a0587 100644 --- a/pages/implementations/testcases.md +++ b/pages/implementations/testcases.md @@ -18,7 +18,7 @@ In the `testcases.json` file, test cases are included on the `testcases` array, - `ruleId`: Unique identifier for the rule. - `ruleName`: Title of the rule the test case is for - `rulePage`: Page containing a detailed rule description. -- `requirementsMapping`: Array of success criteria and other accessibility requirements not satisfied when the rule `failed` +- `ruleAccessibilityRequirements`: Array of success criteria and other accessibility requirements not satisfied when the rule `failed` ```json { @@ -33,7 +33,7 @@ In the `testcases.json` file, test cases are included on the `testcases` array, "ruleId": "5f99a7", "ruleName": "ARIA attribute is valid", "rulePage": "https://act-rules.github.io/rules/5f99a7", - "requirementsMapping": ["wcag20:4.1.2"] + "ruleAccessibilityRequirements": ["wcag20:4.1.2"] }, ... ] } ``` @@ -42,7 +42,7 @@ In the `testcases.json` file, test cases are included on the `testcases` array, To run the test cases, go through each URL run the necessary tests on that page. Tools and test procedures do not need to have a one-to-one mapping to ACT-R rules. While you could run all tests in an implementation on every test case, for efficiency we recommend doing one of the following: -1. Only run tests relevant for the `requirementsMapping` (e.g. for a test case that maps to success criterion 1.1.1, only run tests related to success criterion 1.1.1) +1. Only run tests relevant for the `ruleAccessibilityRequirements` (e.g. for a test case that maps to success criterion 1.1.1, only run tests related to success criterion 1.1.1) 2. Maintain a manual many-to-many mapping of rules in your implementation to ACT-R Rules diff --git a/build/create-file.js b/utils/create-file.js similarity index 100% rename from build/create-file.js rename to utils/create-file.js From b820fda0fa8f2e068d320930c54d5d311200c6b4 Mon Sep 17 00:00:00 2001 From: jkodu Date: Wed, 12 Jun 2019 17:38:25 +0100 Subject: [PATCH 02/20] add implementation to coverage/ overview --- build/get-implementations-data.js | 4 ++-- build/implementations/get-implementation.js | 2 +- .../get-testcase-assertions.js | 10 ---------- package.json | 1 + src/templates/coverage.js | 20 ++++++++++++------- 5 files changed, 17 insertions(+), 20 deletions(-) diff --git a/build/get-implementations-data.js b/build/get-implementations-data.js index 67f871d283..6103a9c86b 100644 --- a/build/get-implementations-data.js +++ b/build/get-implementations-data.js @@ -26,9 +26,9 @@ const init = async () => { * get implementation metrics from report */ const implementation = await getImplementation(framedReport) - + const filename = tool.split(' ').join('-').toLowerCase(); await createFile( - `public/implementations/${tool}.json`, + `public/implementations/${filename}.json`, JSON.stringify(implementation, null, 2) ) } diff --git a/build/implementations/get-implementation.js b/build/implementations/get-implementation.js index f7d24a598c..8a991e8cac 100644 --- a/build/implementations/get-implementation.js +++ b/build/implementations/get-implementation.js @@ -20,7 +20,7 @@ const getImplementation = async framedReports => { implementation } }) - .filter(result => (result.implementation && result.implementation.length > 0)) + .filter(result => (result.implementation && result.implementation.length)) } module.exports = getImplementation \ No newline at end of file diff --git a/build/implementations/get-testcase-assertions.js b/build/implementations/get-testcase-assertions.js index adeda8e3c6..06a6afe9e2 100644 --- a/build/implementations/get-testcase-assertions.js +++ b/build/implementations/get-testcase-assertions.js @@ -2,25 +2,15 @@ const getAssertionSource = require('./get-assertion-source') /** * Get all assertions for given testcase - * Note: cache assertion for easier look-up * * @param {Array} assertions assertions * @param {String} relativeUrl relative url of testcase */ const getTestcaseAssertions = (assertions, relativeUrl) => { - var cache = {} - - const cacheKeys = Object.keys(cache); - if (cacheKeys.includes(relativeUrl)) { - return cache[relativeUrl] - } - const testcaseAssertions = assertions.filter(assertion => { const source = getAssertionSource(assertion) return source.includes(relativeUrl) }) - - cache[relativeUrl] = testcaseAssertions; return testcaseAssertions; } diff --git a/package.json b/package.json index 83d406ee62..531864f0f2 100644 --- a/package.json +++ b/package.json @@ -196,6 +196,7 @@ "tool": "Access42 (RGAA)", "data": { "type": "NPM", + "url": "https://github.com/act-rules/act-rules-implementation-rgaa/tree/master/reports", "exec": "npm install https://github.com/act-rules/act-rules-implementation-rgaa/tarball/master", "path": "act-rules-implementation-rgaa/reports/*.json" } diff --git a/src/templates/coverage.js b/src/templates/coverage.js index ccca1e80fa..927fc0644a 100644 --- a/src/templates/coverage.js +++ b/src/templates/coverage.js @@ -1,14 +1,15 @@ import React from 'react' import Layout from '../components/layout' import { graphql } from 'gatsby' -import implementations from './../../_data/implementations' import SEO from '../components/seo' +import pkg from './../../package.json' export default ({ data }) => { const { markdownRemark, site } = data const { html, frontmatter } = markdownRemark const updatedTitle = `${frontmatter.title} | ${site.siteMetadata.title}` + const { config: { implementations } } = pkg return ( @@ -23,24 +24,29 @@ export default ({ data }) => { # Tool Name - Version + {/* Version */} Created By Report {implementations.map((row, index) => { + const { provider, tool, data } = row + const reportUrl = data.type === `JSON` + ? data.path + : data.url return ( - + {index + 1} - {row.vendorTool} - {row.vendorToolVersion} - {row.vendorName} + {tool} + {/* TODO: */} + {/* {row.vendorToolVersion} */} + {provider} View Report From 460a54871c6f83e2b91893d0462c7c0407430201 Mon Sep 17 00:00:00 2001 From: jkodu Date: Wed, 12 Jun 2019 18:32:26 +0100 Subject: [PATCH 03/20] add metrics to website --- build/get-implementations-data.js | 69 +++++++++++++++- src/components/layout/index.scss | 4 +- src/pages/rules.js | 3 + src/templates/rule.js | 8 ++ src/utils/render-fragments.js | 130 ++++++++++++++++++++++++++---- 5 files changed, 196 insertions(+), 18 deletions(-) diff --git a/build/get-implementations-data.js b/build/get-implementations-data.js index 6103a9c86b..7fd27542ea 100644 --- a/build/get-implementations-data.js +++ b/build/get-implementations-data.js @@ -12,6 +12,11 @@ const init = async () => { throw new Error('No implementations are specified in `config` of `package.json`') } + /** + * Collect all implementations from various vendors + */ + const implementationReports = {}; + for (let item of implementations) { const { provider, tool, data } = item @@ -25,13 +30,71 @@ const init = async () => { /** * get implementation metrics from report */ - const implementation = await getImplementation(framedReport) + const implementationStats = await getImplementation(framedReport) + + + /** + * create rule based metric + */ + const report = { + tool, + provider, + data, + implementationStats + } + implementationReports[tool] = report + + /** + * Note: + * These files are only generated for debugging + */ const filename = tool.split(' ').join('-').toLowerCase(); await createFile( - `public/implementations/${filename}.json`, - JSON.stringify(implementation, null, 2) + `_data/implementations/${filename}.json`, + JSON.stringify(report, null, 2) ) } + + /** + * transform data, to be grouped by rule id. + */ + const groupedMetricByRuleId = {} + + Object.values(implementationReports) + .forEach(report => { + const { tool, provider, data, implementationStats } = report; + + implementationStats + .forEach(({ ruleId, implementation }) => { + if (!implementation) { + return + } + + const { complete = false } = implementation + if (!complete) { + return + } + + if (!groupedMetricByRuleId[ruleId]) { + groupedMetricByRuleId[ruleId] = [] + } + + groupedMetricByRuleId[ruleId].push({ + tool, + provider, + data, + implementation + }) + }) + }) + + /** + * Create metrics in `_data` for usage in `site` + */ + await createFile( + `_data/implementations-metrics.json`, + JSON.stringify(groupedMetricByRuleId, null, 2) + ) } init() diff --git a/src/components/layout/index.scss b/src/components/layout/index.scss index 7375880bf7..7f6311d390 100644 --- a/src/components/layout/index.scss +++ b/src/components/layout/index.scss @@ -161,7 +161,8 @@ section.layout-container { } div.meta { - h3.heading { + h3.heading, + span.heading { padding: 0.25rem 0.5rem; background-color: $sep; border: 1px solid $transparent; @@ -170,6 +171,7 @@ section.layout-container { font-weight: bold; margin-top: 1em; font-size: 90%; + color: inherit; cursor: auto; &:hover { text-decoration: none; diff --git a/src/pages/rules.js b/src/pages/rules.js index d567184c99..e6b9260e71 100644 --- a/src/pages/rules.js +++ b/src/pages/rules.js @@ -6,6 +6,7 @@ import showdown from 'showdown' import { getAccessibilityRequirements, getInputRulesForRule, + getImplementationsCount } from './../utils/render-fragments' export default ({ data }) => { @@ -56,6 +57,8 @@ export default ({ data }) => { {/* input rules */} {getInputRulesForRule(input_rules, allRules.edges, true)} + {/* implementation count */} + {getImplementationsCount(slug)} ) })} diff --git a/src/templates/rule.js b/src/templates/rule.js index 241b7737e9..968f695c84 100644 --- a/src/templates/rule.js +++ b/src/templates/rule.js @@ -12,6 +12,8 @@ import { getAuthors, getInputRulesForRule, getInputAspects, + getImplementations, + getImplementationsLink } from './../utils/render-fragments' import SEO from '../components/seo' import { contributors, repository, config } from './../../package.json' @@ -81,6 +83,8 @@ export default ({ data }) => { repository.url, `_rules/${relativePath}` )} + {/* implementations */} + {getImplementations(slug)} {/* acknowledgements */}
@@ -98,8 +102,12 @@ export default ({ data }) => {
    + {/* glossary */} {getGlossaryUsedLink(slug, allGlossary)} + {/* changelog */} {getChangelogLink(ruleChangelog)} + {/* implementations */} + {getImplementationsLink(slug)}
  • Acknowledgements
  • diff --git a/src/utils/render-fragments.js b/src/utils/render-fragments.js index 5224e3b8b2..99444eeca4 100644 --- a/src/utils/render-fragments.js +++ b/src/utils/render-fragments.js @@ -2,6 +2,69 @@ import React from 'react' import scUrls from './../../_data/sc-urls' import { Link } from 'gatsby' import glossaryUsages from './../../_data/glossary-usages.json' +import implementationMetrics from './../../_data/implementations-metrics.json' + +export const getImplementations = slug => { + const ruleId = slug.replace('rules/', '') + const metrics = implementationMetrics[ruleId] + if (!metrics) { + return null + } + return ( + <> + +

    Implementations

    +
    + + + + + + + + + + + {metrics.map((metric, index) => { + const { provider, tool, data } = metric + const reportUrl = data.type === `JSON` + ? data.path + : data.url + return ( + + + + + + + ) + })} + +
    #Tool NameCreated ByReport
    {index + 1}{tool}{provider} + + View Report + +
    + + ) +} + +export const getImplementationsLink = slug => { + const ruleId = slug.replace('rules/', '') + const metrics = implementationMetrics[ruleId] + if (!metrics) { + return null + } + return ( +
  • + Implementations ({metrics.length}) +
  • + ) +} export const getChangelog = (changelog, url, file) => { if (!changelog.length) { @@ -349,20 +412,59 @@ export function getInputRulesForRule(

    Input Rules

    - {inputRules.map(inputRuleId => { - const atomicRule = allRules.find( - rule => rule.node.frontmatter.id === inputRuleId - ) - const aHref = stripBasePath - ? atomicRule.node.fields.slug.replace('rules/', '') - : atomicRule.node.fields.slug - const name = atomicRule.node.frontmatter.name - return ( - - {name} - - ) - })} +
      + {inputRules.map(inputRuleId => { + const atomicRule = allRules.find( + rule => rule.node.frontmatter.id === inputRuleId + ) + const aHref = stripBasePath + ? atomicRule.node.fields.slug.replace('rules/', '') + : atomicRule.node.fields.slug + const name = atomicRule.node.frontmatter.name + return ( +
    • + + {name} + +
    • + ) + })} +
    +
    +
    + ) +} + + +export function getImplementationsCount(slug) { + const ruleId = slug.replace('rules/', '') + const metrics = implementationMetrics[ruleId] + if (!metrics) { + return null + } + return ( +
    +
    +

    Implementations ({metrics.length})

    +
      + { + metrics.map((metric, index) => { + const { provider, tool, data } = metric + const reportUrl = data.type === `JSON` + ? data.path + : data.url + return ( +
    • + + {tool} ({provider}) + +
    • + ) + }) + } +
    ) From ee046e772ab74746c88f4a2c6df049e421e565ed Mon Sep 17 00:00:00 2001 From: jkodu Date: Wed, 12 Jun 2019 18:33:22 +0100 Subject: [PATCH 04/20] format (prettierr) --- build/get-implementations-data.js | 192 +++++++++--------- build/implementations/get-assertion-source.js | 19 +- build/implementations/get-assertions.js | 16 +- .../get-best-matching-rules.js | 22 +- build/implementations/get-framed-report.js | 70 ++++--- build/implementations/get-implementation.js | 28 +-- .../implementations/get-rule-mapping-state.js | 76 +++---- build/implementations/get-rule-mapping.js | 88 ++++---- .../get-testcase-assertions.js | 14 +- build/implementations/get-testcase-mapping.js | 40 ++-- .../get-testcase-relative-url.js | 12 +- .../get-testcases-grouped-by-rule.js | 24 +-- gatsby/create-testcases-of-all-rules.js | 2 +- src/pages/rules.js | 2 +- src/templates/coverage.js | 8 +- src/templates/rule.js | 2 +- src/utils/render-fragments.js | 27 +-- 17 files changed, 316 insertions(+), 326 deletions(-) diff --git a/build/get-implementations-data.js b/build/get-implementations-data.js index 7fd27542ea..54a8731e52 100644 --- a/build/get-implementations-data.js +++ b/build/get-implementations-data.js @@ -1,105 +1,109 @@ -const { config: { implementations } } = require('./../package.json') +const { + config: { implementations }, +} = require('./../package.json') const getFramedReport = require('./implementations/get-framed-report') const getImplementation = require('./implementations/get-implementation') const createFile = require('./../utils/create-file') /** - * Create implementation metrics, that can be used in the site, + * Create implementation metrics, that can be used in the site, * for each `implementation` provided as configuration in `package.json`. */ const init = async () => { - if (!implementations || !Object.keys(implementations).length) { - throw new Error('No implementations are specified in `config` of `package.json`') - } - - /** - * Collect all implementations from various vendors - */ - const implementationReports = {}; - - for (let item of implementations) { - const { provider, tool, data } = item - - console.info(`Get implementation data of ${tool} by ${provider}\n`) - - /** - * fetch report & frame as required - */ - const framedReport = await getFramedReport(data) - - /** - * get implementation metrics from report - */ - const implementationStats = await getImplementation(framedReport) - - - /** - * create rule based metric - */ - const report = { - tool, - provider, - data, - implementationStats - } - implementationReports[tool] = report - - /** - * Note: - * These files are only generated for debugging - */ - const filename = tool.split(' ').join('-').toLowerCase(); - await createFile( - `_data/implementations/${filename}.json`, - JSON.stringify(report, null, 2) - ) - } - - /** - * transform data, to be grouped by rule id. - */ - const groupedMetricByRuleId = {} - - Object.values(implementationReports) - .forEach(report => { - const { tool, provider, data, implementationStats } = report; - - implementationStats - .forEach(({ ruleId, implementation }) => { - if (!implementation) { - return - } - - const { complete = false } = implementation - if (!complete) { - return - } - - if (!groupedMetricByRuleId[ruleId]) { - groupedMetricByRuleId[ruleId] = [] - } - - groupedMetricByRuleId[ruleId].push({ - tool, - provider, - data, - implementation - }) - }) - }) - - /** - * Create metrics in `_data` for usage in `site` - */ - await createFile( - `_data/implementations-metrics.json`, - JSON.stringify(groupedMetricByRuleId, null, 2) - ) + if (!implementations || !Object.keys(implementations).length) { + throw new Error( + 'No implementations are specified in `config` of `package.json`' + ) + } + + /** + * Collect all implementations from various vendors + */ + const implementationReports = {} + + for (let item of implementations) { + const { provider, tool, data } = item + + console.info(`Get implementation data of ${tool} by ${provider}\n`) + + /** + * fetch report & frame as required + */ + const framedReport = await getFramedReport(data) + + /** + * get implementation metrics from report + */ + const implementationStats = await getImplementation(framedReport) + + /** + * create rule based metric + */ + const report = { + tool, + provider, + data, + implementationStats, + } + implementationReports[tool] = report + + /** + * Note: + * These files are only generated for debugging + */ + const filename = tool + .split(' ') + .join('-') + .toLowerCase() + await createFile( + `_data/implementations/${filename}.json`, + JSON.stringify(report, null, 2) + ) + } + + /** + * transform data, to be grouped by rule id. + */ + const groupedMetricByRuleId = {} + + Object.values(implementationReports).forEach(report => { + const { tool, provider, data, implementationStats } = report + + implementationStats.forEach(({ ruleId, implementation }) => { + if (!implementation) { + return + } + + const { complete = false } = implementation + if (!complete) { + return + } + + if (!groupedMetricByRuleId[ruleId]) { + groupedMetricByRuleId[ruleId] = [] + } + + groupedMetricByRuleId[ruleId].push({ + tool, + provider, + data, + implementation, + }) + }) + }) + + /** + * Create metrics in `_data` for usage in `site` + */ + await createFile( + `_data/implementations-metrics.json`, + JSON.stringify(groupedMetricByRuleId, null, 2) + ) } init() - .then(() => console.info(`Implementations data generated.`)) - .catch(err => { - console.error(err); - process.exit(1) - }) \ No newline at end of file + .then(() => console.info(`Implementations data generated.`)) + .catch(err => { + console.error(err) + process.exit(1) + }) diff --git a/build/implementations/get-assertion-source.js b/build/implementations/get-assertion-source.js index 13b6dde312..7010f56368 100644 --- a/build/implementations/get-assertion-source.js +++ b/build/implementations/get-assertion-source.js @@ -1,24 +1,23 @@ const flat = require('flat') const isUrl = require('is-url') -const { www: { url: siteUrl } } = require('./../../package.json') +const { + www: { url: siteUrl }, +} = require('./../../package.json') /** * Given an assertion object * - get `source`, which resembles closest to the url of the testcase - * + * * Achieved by * - flatten the given object * - and verity if values are of type `url` and has `siteUrl` * @param {Object} assertion assertion */ const getAssertionSource = assertion => { - const flattenedAssertion = flat(assertion); - return Object.values(flattenedAssertion).find(value => { - return ( - isUrl(value) && - value.includes(siteUrl) - ) - }) + const flattenedAssertion = flat(assertion) + return Object.values(flattenedAssertion).find(value => { + return isUrl(value) && value.includes(siteUrl) + }) } -module.exports = getAssertionSource \ No newline at end of file +module.exports = getAssertionSource diff --git a/build/implementations/get-assertions.js b/build/implementations/get-assertions.js index 297c486834..874b217e34 100644 --- a/build/implementations/get-assertions.js +++ b/build/implementations/get-assertions.js @@ -1,17 +1,15 @@ /** * Get assertions from framed reports - * + * * @param {Object|Array} framedReports implementation reports */ const getAssertions = framedReports => { - const reports = Array.isArray(framedReports) - ? framedReports - : [framedReports] + const reports = Array.isArray(framedReports) ? framedReports : [framedReports] - return reports.reduce((out, report) => { - out.push(...report[`@graph`]) - return out - }, []) + return reports.reduce((out, report) => { + out.push(...report[`@graph`]) + return out + }, []) } -module.exports = getAssertions; \ No newline at end of file +module.exports = getAssertions diff --git a/build/implementations/get-best-matching-rules.js b/build/implementations/get-best-matching-rules.js index cf1baeff82..a9422971b6 100644 --- a/build/implementations/get-best-matching-rules.js +++ b/build/implementations/get-best-matching-rules.js @@ -1,20 +1,20 @@ /** * Given a set of assertion results, get best fit, based on outcome mapping - * + * * @param {Array} ruleAsserts mapped assertions */ const getBestMatchingRules = ruleAsserts => { - const mappedRules = ruleAsserts.filter(({ mapping }) => mapping !== false) - if (!mappedRules) { - return - } + const mappedRules = ruleAsserts.filter(({ mapping }) => mapping !== false) + if (!mappedRules) { + return + } - const completeRules = mappedRules.filter(({ complete }) => complete === true) - if (!completeRules) { - return mappedRules; - } + const completeRules = mappedRules.filter(({ complete }) => complete === true) + if (!completeRules) { + return mappedRules + } - return completeRules; + return completeRules } -module.exports = getBestMatchingRules \ No newline at end of file +module.exports = getBestMatchingRules diff --git a/build/implementations/get-framed-report.js b/build/implementations/get-framed-report.js index 49616810b2..a9508f043f 100644 --- a/build/implementations/get-framed-report.js +++ b/build/implementations/get-framed-report.js @@ -5,57 +5,55 @@ const jsonld = require('jsonld') const { exec } = require('child_process') const frameConfig = require('./json-ld-frame-config') - const getFramedReport = async options => { - const { type } = options; + const { type } = options - if (![`NPM`, `JSON`].includes(type)) { - throw new Error('Provided type ${type} for report is not val`') - } + if (![`NPM`, `JSON`].includes(type)) { + throw new Error('Provided type ${type} for report is not val`') + } - if (type === `JSON`) { - const { path: url } = options; - const { data } = await axios.get(url); - return await jsonld.frame(data, frameConfig) - } + if (type === `JSON`) { + const { path: url } = options + const { data } = await axios.get(url) + return await jsonld.frame(data, frameConfig) + } - if (type === `NPM`) { - const { exec: command, path } = options; + if (type === `NPM`) { + const { exec: command, path } = options - // `npm i module` - await executeCommand(command) + // `npm i module` + await executeCommand(command) - const reports = globby.sync([`./node_modules/${path}`]) - .map(reportPath => { - const fileContent = fs.readFileSync(reportPath, { encoding: 'utf-8' }) - return JSON.parse(fileContent) - }) + const reports = globby.sync([`./node_modules/${path}`]).map(reportPath => { + const fileContent = fs.readFileSync(reportPath, { encoding: 'utf-8' }) + return JSON.parse(fileContent) + }) - const result = [] + const result = [] - for (let report of reports) { - const framedReport = await jsonld.frame(report, frameConfig) - result.push(framedReport) - } + for (let report of reports) { + const framedReport = await jsonld.frame(report, frameConfig) + result.push(framedReport) + } - return result; - } + return result + } } module.exports = getFramedReport - /** * Execute a given command - * + * * @param {String} command command to execute */ async function executeCommand(command) { - return new Promise((resolve, reject) => - exec(command, (err, result) => { - if (err) { - reject(err) - } - resolve(result) - })) -} \ No newline at end of file + return new Promise((resolve, reject) => + exec(command, (err, result) => { + if (err) { + reject(err) + } + resolve(result) + }) + ) +} diff --git a/build/implementations/get-implementation.js b/build/implementations/get-implementation.js index 8a991e8cac..d10e0edcc4 100644 --- a/build/implementations/get-implementation.js +++ b/build/implementations/get-implementation.js @@ -4,23 +4,23 @@ const getRuleMapping = require('./get-rule-mapping') /** * Get implementation metric from submitted report - * + * * @param {Object|Array} framedReports implementation reports */ const getImplementation = async framedReports => { - const assertions = getAssertions(framedReports) - const testcasesGroupedByRuleId = await getTestcasesGroupedByRule() + const assertions = getAssertions(framedReports) + const testcasesGroupedByRuleId = await getTestcasesGroupedByRule() - return Object.keys(testcasesGroupedByRuleId) - .map(ruleId => { - const ruleTestcases = testcasesGroupedByRuleId[ruleId] - const implementation = getRuleMapping(ruleTestcases, assertions) - return { - ruleId, - implementation - } - }) - .filter(result => (result.implementation && result.implementation.length)) + return Object.keys(testcasesGroupedByRuleId) + .map(ruleId => { + const ruleTestcases = testcasesGroupedByRuleId[ruleId] + const implementation = getRuleMapping(ruleTestcases, assertions) + return { + ruleId, + implementation, + } + }) + .filter(result => result.implementation && result.implementation.length) } -module.exports = getImplementation \ No newline at end of file +module.exports = getImplementation diff --git a/build/implementations/get-rule-mapping-state.js b/build/implementations/get-rule-mapping-state.js index cb44243ecb..1e8c334a1e 100644 --- a/build/implementations/get-rule-mapping-state.js +++ b/build/implementations/get-rule-mapping-state.js @@ -1,48 +1,50 @@ const assert = require('assert') const outcomeMapping = { - failed: ['failed', 'cantTell'], - fail: ['failed', 'cantTell'], - passed: ['passed', 'cantTell', 'inapplicable'], - pass: ['passed', 'cantTell', 'inapplicable'], - inapplicable: ['passed', 'cantTell', 'inapplicable', 'untested'], + failed: ['failed', 'cantTell'], + fail: ['failed', 'cantTell'], + passed: ['passed', 'cantTell', 'inapplicable'], + pass: ['passed', 'cantTell', 'inapplicable'], + inapplicable: ['passed', 'cantTell', 'inapplicable', 'untested'], } /** * Get rule state based on given assertions - * - * @param {Array} assertions + * + * @param {Array} assertions */ const getRuleMappingState = assertions => { - const mapping = assertions.some(({ actual, expected }) => - expected === 'failed' && ['failed', 'cantTell'].includes(actual)) - - if (!mapping) { - return { mapping: false }; - } - - const complete = assertions.every(({ expected, actual }) => { - return expected !== 'failed' || actual === 'failed' - }) - - const incorrect = assertions - .filter((data) => { - const { expected, actual } = data - assert(outcomeMapping[expected], `Unknown result type ${expected}`) - - return !outcomeMapping[expected].includes(actual) - }) - .map(({ url }) => url) - - // const fullAuto = undefined - - return { - complete, - incorrect, - assertions: assertions.map(({ expected, actual, url }) => { - return { expected, actual, url } - }) - } + const mapping = assertions.some( + ({ actual, expected }) => + expected === 'failed' && ['failed', 'cantTell'].includes(actual) + ) + + if (!mapping) { + return { mapping: false } + } + + const complete = assertions.every(({ expected, actual }) => { + return expected !== 'failed' || actual === 'failed' + }) + + const incorrect = assertions + .filter(data => { + const { expected, actual } = data + assert(outcomeMapping[expected], `Unknown result type ${expected}`) + + return !outcomeMapping[expected].includes(actual) + }) + .map(({ url }) => url) + + // const fullAuto = undefined + + return { + complete, + incorrect, + assertions: assertions.map(({ expected, actual, url }) => { + return { expected, actual, url } + }), + } } -module.exports = getRuleMappingState \ No newline at end of file +module.exports = getRuleMappingState diff --git a/build/implementations/get-rule-mapping.js b/build/implementations/get-rule-mapping.js index b6e2c9e12f..2b59a43dfb 100644 --- a/build/implementations/get-rule-mapping.js +++ b/build/implementations/get-rule-mapping.js @@ -5,49 +5,49 @@ const getTestcaseAssertions = require('./get-testcase-assertions') const getTestCaseMapping = require('./get-testcase-mapping') function getRuleMapping(testcases, assertions) { - const ruleData = {} - - testcases.forEach(tc => { - const relativeUrl = getTestcaseRelativeUrl(tc.url) - const tcAssertions = getTestcaseAssertions(assertions, relativeUrl) - - // Create a mapping for each assertion - tcAssertions.forEach(assertion => { - const testMapping = getTestCaseMapping(assertion, tc) - if (!testMapping || testMapping.actual === 'untested') { - return - } - if (!ruleData[testMapping.title]) { - ruleData[testMapping.title] = [] - } - ruleData[testMapping.title].push(testMapping) - }) - }) - - for (tc of testcases) { - const relativeUrl = getTestcaseRelativeUrl(tc.url) - - // Push untested results for every test case without an assertion - Object.values(ruleData).forEach(testMappings => { - if (!testMappings.some(({ url }) => url && url.includes(relativeUrl))) { - testMappings.push({ - title: testMappings[0].title, - expected: tc.expected, - actual: 'untested', - url: tc.url - }) - } - }) - } - - const ruleAsserts = Object.values(ruleData).map(data => { - const mappingState = getRuleMappingState(data) - return { - ...mappingState - } - }) - - return getBestMatchingRules(ruleAsserts) + const ruleData = {} + + testcases.forEach(tc => { + const relativeUrl = getTestcaseRelativeUrl(tc.url) + const tcAssertions = getTestcaseAssertions(assertions, relativeUrl) + + // Create a mapping for each assertion + tcAssertions.forEach(assertion => { + const testMapping = getTestCaseMapping(assertion, tc) + if (!testMapping || testMapping.actual === 'untested') { + return + } + if (!ruleData[testMapping.title]) { + ruleData[testMapping.title] = [] + } + ruleData[testMapping.title].push(testMapping) + }) + }) + + for (tc of testcases) { + const relativeUrl = getTestcaseRelativeUrl(tc.url) + + // Push untested results for every test case without an assertion + Object.values(ruleData).forEach(testMappings => { + if (!testMappings.some(({ url }) => url && url.includes(relativeUrl))) { + testMappings.push({ + title: testMappings[0].title, + expected: tc.expected, + actual: 'untested', + url: tc.url, + }) + } + }) + } + + const ruleAsserts = Object.values(ruleData).map(data => { + const mappingState = getRuleMappingState(data) + return { + ...mappingState, + } + }) + + return getBestMatchingRules(ruleAsserts) } -module.exports = getRuleMapping; \ No newline at end of file +module.exports = getRuleMapping diff --git a/build/implementations/get-testcase-assertions.js b/build/implementations/get-testcase-assertions.js index 06a6afe9e2..64931efb97 100644 --- a/build/implementations/get-testcase-assertions.js +++ b/build/implementations/get-testcase-assertions.js @@ -2,16 +2,16 @@ const getAssertionSource = require('./get-assertion-source') /** * Get all assertions for given testcase - * + * * @param {Array} assertions assertions * @param {String} relativeUrl relative url of testcase */ const getTestcaseAssertions = (assertions, relativeUrl) => { - const testcaseAssertions = assertions.filter(assertion => { - const source = getAssertionSource(assertion) - return source.includes(relativeUrl) - }) - return testcaseAssertions; + const testcaseAssertions = assertions.filter(assertion => { + const source = getAssertionSource(assertion) + return source.includes(relativeUrl) + }) + return testcaseAssertions } -module.exports = getTestcaseAssertions \ No newline at end of file +module.exports = getTestcaseAssertions diff --git a/build/implementations/get-testcase-mapping.js b/build/implementations/get-testcase-mapping.js index 8289a736a8..c1561961b5 100644 --- a/build/implementations/get-testcase-mapping.js +++ b/build/implementations/get-testcase-mapping.js @@ -2,37 +2,37 @@ const getAssertionSource = require('./get-assertion-source') /** * Utility fn to get title from assertion - * + * * @param {Object} assertion assertion * @returns {String} */ const getTitleFromAssertion = assertion => { - const { test, EMTest } = assertion - if (!test) { - return EMTest || null - } - if (typeof test === 'string') { - return test - } - if (test.title) { - return test.title - } - return test['@id'] || '' + const { test, EMTest } = assertion + if (!test) { + return EMTest || null + } + if (typeof test === 'string') { + return test + } + if (test.title) { + return test.title + } + return test['@id'] || '' } /** * Get mapping for a given testcase - * + * * @param {Object} assertion assertion * @param {Object} tc testcase */ const getTestcaseMapping = (assertion, { expected }) => { - return { - title: getTitleFromAssertion(assertion), - url: getAssertionSource(assertion), - expected: expected, - actual: assertion.result.outcome.replace('earl:', '') - } + return { + title: getTitleFromAssertion(assertion), + url: getAssertionSource(assertion), + expected: expected, + actual: assertion.result.outcome.replace('earl:', ''), + } } -module.exports = getTestcaseMapping \ No newline at end of file +module.exports = getTestcaseMapping diff --git a/build/implementations/get-testcase-relative-url.js b/build/implementations/get-testcase-relative-url.js index d23194d3c7..1b57dc0763 100644 --- a/build/implementations/get-testcase-relative-url.js +++ b/build/implementations/get-testcase-relative-url.js @@ -1,13 +1,15 @@ -const { www: { url: siteUrl } } = require('./../../package.json') +const { + www: { url: siteUrl }, +} = require('./../../package.json') /** * Get relative (suffix) from url - * + * * @param {String} url url */ const getTestcaseRelativeUrl = url => { - const urlPrefix = `${siteUrl}/testcases/` - return url.substr(url.indexOf(urlPrefix)) + const urlPrefix = `${siteUrl}/testcases/` + return url.substr(url.indexOf(urlPrefix)) } -module.exports = getTestcaseRelativeUrl \ No newline at end of file +module.exports = getTestcaseRelativeUrl diff --git a/build/implementations/get-testcases-grouped-by-rule.js b/build/implementations/get-testcases-grouped-by-rule.js index d010c49c1b..78bfe3d16b 100644 --- a/build/implementations/get-testcases-grouped-by-rule.js +++ b/build/implementations/get-testcases-grouped-by-rule.js @@ -6,18 +6,18 @@ const { config } = require('./../../package.json') * - group them by `ruleId` */ const getTestcasesGroupedByRule = async () => { - const testcasesUrl = config['testcases-url'] - const { data } = await axios.get(testcasesUrl) - const { testcases } = data + const testcasesUrl = config['testcases-url'] + const { data } = await axios.get(testcasesUrl) + const { testcases } = data - return testcases.reduce((out, testcase) => { - const { ruleId } = testcase - if (!out[ruleId]) { - out[ruleId] = [] - } - out[ruleId].push(testcase) - return out - }, {}) + return testcases.reduce((out, testcase) => { + const { ruleId } = testcase + if (!out[ruleId]) { + out[ruleId] = [] + } + out[ruleId].push(testcase) + return out + }, {}) } -module.exports = getTestcasesGroupedByRule \ No newline at end of file +module.exports = getTestcasesGroupedByRule diff --git a/gatsby/create-testcases-of-all-rules.js b/gatsby/create-testcases-of-all-rules.js index 85f1cd5cd0..ef2a3808bd 100644 --- a/gatsby/create-testcases-of-all-rules.js +++ b/gatsby/create-testcases-of-all-rules.js @@ -101,7 +101,7 @@ const createTestcasesOfAllRules = options => { ruleId, ruleName, rulePage: `${url}/${slug}`, - ruleAccessibilityRequirements + ruleAccessibilityRequirements, } out.push(testcase) diff --git a/src/pages/rules.js b/src/pages/rules.js index e6b9260e71..883e9a67b6 100644 --- a/src/pages/rules.js +++ b/src/pages/rules.js @@ -6,7 +6,7 @@ import showdown from 'showdown' import { getAccessibilityRequirements, getInputRulesForRule, - getImplementationsCount + getImplementationsCount, } from './../utils/render-fragments' export default ({ data }) => { diff --git a/src/templates/coverage.js b/src/templates/coverage.js index 927fc0644a..6fe54e6202 100644 --- a/src/templates/coverage.js +++ b/src/templates/coverage.js @@ -9,7 +9,9 @@ export default ({ data }) => { const { html, frontmatter } = markdownRemark const updatedTitle = `${frontmatter.title} | ${site.siteMetadata.title}` - const { config: { implementations } } = pkg + const { + config: { implementations }, + } = pkg return ( @@ -32,9 +34,7 @@ export default ({ data }) => { {implementations.map((row, index) => { const { provider, tool, data } = row - const reportUrl = data.type === `JSON` - ? data.path - : data.url + const reportUrl = data.type === `JSON` ? data.path : data.url return ( {index + 1} diff --git a/src/templates/rule.js b/src/templates/rule.js index 968f695c84..794bed3251 100644 --- a/src/templates/rule.js +++ b/src/templates/rule.js @@ -13,7 +13,7 @@ import { getInputRulesForRule, getInputAspects, getImplementations, - getImplementationsLink + getImplementationsLink, } from './../utils/render-fragments' import SEO from '../components/seo' import { contributors, repository, config } from './../../package.json' diff --git a/src/utils/render-fragments.js b/src/utils/render-fragments.js index 99444eeca4..7a5346daaf 100644 --- a/src/utils/render-fragments.js +++ b/src/utils/render-fragments.js @@ -27,20 +27,14 @@ export const getImplementations = slug => { {metrics.map((metric, index) => { const { provider, tool, data } = metric - const reportUrl = data.type === `JSON` - ? data.path - : data.url + const reportUrl = data.type === `JSON` ? data.path : data.url return ( {index + 1} {tool} {provider} - + View Report @@ -423,8 +417,7 @@ export function getInputRulesForRule( const name = atomicRule.node.frontmatter.name return (
  • - + {name}
  • @@ -436,7 +429,6 @@ export function getInputRulesForRule( ) } - export function getImplementationsCount(slug) { const ruleId = slug.replace('rules/', '') const metrics = implementationMetrics[ruleId] @@ -448,22 +440,17 @@ export function getImplementationsCount(slug) {

    Implementations ({metrics.length})

      - { - metrics.map((metric, index) => { + {metrics.map((metric, index) => { const { provider, tool, data } = metric - const reportUrl = data.type === `JSON` - ? data.path - : data.url + const reportUrl = data.type === `JSON` ? data.path : data.url return (
    • - + {tool} ({provider})
    • ) - }) - } + })}
    From d9cf79a63613af4df181dd401502f3b8ee4fa34d Mon Sep 17 00:00:00 2001 From: jkodu Date: Thu, 13 Jun 2019 14:49:55 +0100 Subject: [PATCH 05/20] install reports as packages and update implementation script --- build/get-implementations-data.js | 6 +++- build/implementations/get-framed-report.js | 38 +++++----------------- package-lock.json | 16 +++++---- package.json | 19 +++++------ 4 files changed, 32 insertions(+), 47 deletions(-) diff --git a/build/get-implementations-data.js b/build/get-implementations-data.js index 54a8731e52..00b10dc8f6 100644 --- a/build/get-implementations-data.js +++ b/build/get-implementations-data.js @@ -74,8 +74,12 @@ const init = async () => { return } + /** + * Note: + * only build metrics for implementations that are `complete` + */ const { complete = false } = implementation - if (!complete) { + if (complete) { return } diff --git a/build/implementations/get-framed-report.js b/build/implementations/get-framed-report.js index a9508f043f..6cd7ba9ef9 100644 --- a/build/implementations/get-framed-report.js +++ b/build/implementations/get-framed-report.js @@ -2,32 +2,26 @@ const fs = require('fs') const globby = require('globby') const axios = require('axios') const jsonld = require('jsonld') -const { exec } = require('child_process') const frameConfig = require('./json-ld-frame-config') const getFramedReport = async options => { - const { type } = options + const { type, path } = options if (![`NPM`, `JSON`].includes(type)) { throw new Error('Provided type ${type} for report is not val`') } if (type === `JSON`) { - const { path: url } = options - const { data } = await axios.get(url) + const { data } = await axios.get(path) return await jsonld.frame(data, frameConfig) } if (type === `NPM`) { - const { exec: command, path } = options - - // `npm i module` - await executeCommand(command) - - const reports = globby.sync([`./node_modules/${path}`]).map(reportPath => { - const fileContent = fs.readFileSync(reportPath, { encoding: 'utf-8' }) - return JSON.parse(fileContent) - }) + const reports = globby.sync([path]) + .map(reportPath => { + const fileContent = fs.readFileSync(reportPath, { encoding: 'utf-8' }) + return JSON.parse(fileContent) + }) const result = [] @@ -40,20 +34,4 @@ const getFramedReport = async options => { } } -module.exports = getFramedReport - -/** - * Execute a given command - * - * @param {String} command command to execute - */ -async function executeCommand(command) { - return new Promise((resolve, reject) => - exec(command, (err, result) => { - if (err) { - reject(err) - } - resolve(result) - }) - ) -} +module.exports = getFramedReport \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 098bae4255..068fe0e4dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1641,9 +1641,17 @@ "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", "dev": true }, + "act-rules-implementation-access-engine": { + "version": "git+https://git@github.com/act-rules/act-rules-implementation-access-engine.git#fc89e8142ff8d2ad37ee411cbf3801b44320df43", + "from": "git+https://git@github.com/act-rules/act-rules-implementation-access-engine.git" + }, + "act-rules-implementation-axe-core": { + "version": "git+https://git@github.com/act-rules/act-rules-implementation-axe-core.git#3d61261e7998e2b753eac465cd4dfb316269f0ca", + "from": "git+https://git@github.com/act-rules/act-rules-implementation-axe-core.git" + }, "act-rules-implementation-rgaa": { - "version": "https://github.com/act-rules/act-rules-implementation-rgaa/tarball/master", - "integrity": "sha512-5qtUVoNIymuSUl7SH91MTcASE5dfaZQtWte/8HWu7jfTUCt22uPkrRskVgCdbWBLyLqx6bPJR6Zqj662VKi8Xg==" + "version": "git+https://git@github.com/act-rules/act-rules-implementation-rgaa.git#1d572a40f6879a75d36090c7275c42e4d0d79cee", + "from": "git+https://git@github.com/act-rules/act-rules-implementation-rgaa.git" }, "address": { "version": "1.0.3", @@ -17609,10 +17617,6 @@ } } }, - "testrunner": { - "version": "git+https://github.com/act-rules/act-rules-implementation-rgaa.git#1d572a40f6879a75d36090c7275c42e4d0d79cee", - "from": "git+https://github.com/act-rules/act-rules-implementation-rgaa.git" - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", diff --git a/package.json b/package.json index 531864f0f2..de8e00a21f 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,9 @@ } ], "dependencies": { - "act-rules-implementation-rgaa": "https://github.com/act-rules/act-rules-implementation-rgaa/tarball/master", + "act-rules-implementation-rgaa": "git+https://git@github.com/act-rules/act-rules-implementation-rgaa.git", + "act-rules-implementation-axe-core": "git+https://git@github.com/act-rules/act-rules-implementation-axe-core.git", + "act-rules-implementation-access-engine": "git+https://git@github.com/act-rules/act-rules-implementation-access-engine.git", "axios": "^0.18.1", "fastmatter": "^2.1.1", "flat": "^4.1.0", @@ -115,8 +117,7 @@ "react": "^16.8.6", "react-dom": "^16.8.6", "react-helmet": "^5.2.1", - "showdown": "^1.9.0", - "testrunner": "git+https://github.com/act-rules/act-rules-implementation-rgaa" + "showdown": "^1.9.0" }, "devDependencies": { "husky": "^2.4.0", @@ -171,8 +172,8 @@ "provider": "Level Access", "tool": "Access Engine", "data": { - "type": "JSON", - "path": "https://raw.githubusercontent.com/act-rules/act-rules-implementation-access-engine/master/report.json" + "type": "NPM", + "path": "./node_modules/act-rules-implementation-access-engine/report.json" } }, { @@ -187,17 +188,15 @@ "provider": "Deque Systems", "tool": "Axe", "data": { - "type": "JSON", - "path": "https://raw.githubusercontent.com/act-rules/act-rules-implementation-axe-core/master/report.json" + "type": "NPM", + "path": "./node_modules/act-rules-implementation-axe-core/report.json" } }, { "provider": "Access42", - "tool": "Access42 (RGAA)", + "tool": "RGAA 3.0", "data": { "type": "NPM", - "url": "https://github.com/act-rules/act-rules-implementation-rgaa/tree/master/reports", - "exec": "npm install https://github.com/act-rules/act-rules-implementation-rgaa/tarball/master", "path": "act-rules-implementation-rgaa/reports/*.json" } } From 0e24f944b0e4531b3226dc73dcd1959ee0e21f49 Mon Sep 17 00:00:00 2001 From: jkodu Date: Fri, 14 Jun 2019 13:39:37 +0100 Subject: [PATCH 06/20] add implementation id --- build/get-implementations-data.js | 12 +++---- build/implementations/get-framed-report.js | 35 ++++++++----------- .../implementations/get-rule-mapping-state.js | 1 + build/implementations/get-rule-mapping.js | 8 ++++- build/implementations/json-ld-frame-config.js | 4 +++ package.json | 22 +++--------- 6 files changed, 37 insertions(+), 45 deletions(-) diff --git a/build/get-implementations-data.js b/build/get-implementations-data.js index 00b10dc8f6..ca68a26c98 100644 --- a/build/get-implementations-data.js +++ b/build/get-implementations-data.js @@ -22,14 +22,14 @@ const init = async () => { const implementationReports = {} for (let item of implementations) { - const { provider, tool, data } = item + const { provider, tool, path } = item - console.info(`Get implementation data of ${tool} by ${provider}\n`) + console.info(`Get implementation of ${tool} by ${provider}\n`) /** * fetch report & frame as required */ - const framedReport = await getFramedReport(data) + const framedReport = await getFramedReport(path) /** * get implementation metrics from report @@ -42,7 +42,7 @@ const init = async () => { const report = { tool, provider, - data, + path, implementationStats, } implementationReports[tool] = report @@ -67,7 +67,7 @@ const init = async () => { const groupedMetricByRuleId = {} Object.values(implementationReports).forEach(report => { - const { tool, provider, data, implementationStats } = report + const { tool, provider, path, implementationStats } = report implementationStats.forEach(({ ruleId, implementation }) => { if (!implementation) { @@ -90,7 +90,7 @@ const init = async () => { groupedMetricByRuleId[ruleId].push({ tool, provider, - data, + path, implementation, }) }) diff --git a/build/implementations/get-framed-report.js b/build/implementations/get-framed-report.js index 6cd7ba9ef9..d6e0b7de11 100644 --- a/build/implementations/get-framed-report.js +++ b/build/implementations/get-framed-report.js @@ -2,36 +2,29 @@ const fs = require('fs') const globby = require('globby') const axios = require('axios') const jsonld = require('jsonld') +const isUrl = require('is-url') const frameConfig = require('./json-ld-frame-config') -const getFramedReport = async options => { - const { type, path } = options - - if (![`NPM`, `JSON`].includes(type)) { - throw new Error('Provided type ${type} for report is not val`') - } - - if (type === `JSON`) { +const getFramedReport = async path => { + if (isUrl(path)) { const { data } = await axios.get(path) return await jsonld.frame(data, frameConfig) } - if (type === `NPM`) { - const reports = globby.sync([path]) - .map(reportPath => { - const fileContent = fs.readFileSync(reportPath, { encoding: 'utf-8' }) - return JSON.parse(fileContent) - }) + const reports = globby.sync([path]) + .map(reportPath => { + const fileContent = fs.readFileSync(reportPath, { encoding: 'utf-8' }) + return JSON.parse(fileContent) + }) - const result = [] + const result = [] - for (let report of reports) { - const framedReport = await jsonld.frame(report, frameConfig) - result.push(framedReport) - } - - return result + for (let report of reports) { + const framedReport = await jsonld.frame(report, frameConfig) + result.push(framedReport) } + + return result } module.exports = getFramedReport \ No newline at end of file diff --git a/build/implementations/get-rule-mapping-state.js b/build/implementations/get-rule-mapping-state.js index 1e8c334a1e..61a84d57ef 100644 --- a/build/implementations/get-rule-mapping-state.js +++ b/build/implementations/get-rule-mapping-state.js @@ -39,6 +39,7 @@ const getRuleMappingState = assertions => { // const fullAuto = undefined return { + id: assertions[0].title, complete, incorrect, assertions: assertions.map(({ expected, actual, url }) => { diff --git a/build/implementations/get-rule-mapping.js b/build/implementations/get-rule-mapping.js index 2b59a43dfb..76979db625 100644 --- a/build/implementations/get-rule-mapping.js +++ b/build/implementations/get-rule-mapping.js @@ -1,3 +1,4 @@ +const flat = require('flat') const getTestcaseRelativeUrl = require('./get-testcase-relative-url') const getRuleMappingState = require('./get-rule-mapping-state') const getBestMatchingRules = require('./get-best-matching-rules') @@ -29,7 +30,12 @@ function getRuleMapping(testcases, assertions) { // Push untested results for every test case without an assertion Object.values(ruleData).forEach(testMappings => { - if (!testMappings.some(({ url }) => url && url.includes(relativeUrl))) { + if ( + !Object.values(testMappings) + .some(({ url }) => + url && url.includes(relativeUrl) + ) + ) { testMappings.push({ title: testMappings[0].title, expected: tc.expected, diff --git a/build/implementations/json-ld-frame-config.js b/build/implementations/json-ld-frame-config.js index 458819e666..b20d852ca7 100644 --- a/build/implementations/json-ld-frame-config.js +++ b/build/implementations/json-ld-frame-config.js @@ -85,6 +85,10 @@ module.exports = { '@id': 'dct:source', }, + title: { + '@id': 'dct:title', + }, + assertions: { '@reverse': 'earl:subject', }, diff --git a/package.json b/package.json index de8e00a21f..999c88e5f7 100644 --- a/package.json +++ b/package.json @@ -171,34 +171,22 @@ { "provider": "Level Access", "tool": "Access Engine", - "data": { - "type": "NPM", - "path": "./node_modules/act-rules-implementation-access-engine/report.json" - } + "path": "./node_modules/act-rules-implementation-access-engine/report.json" }, { "provider": "Site Improve", "tool": "Alfa", - "data": { - "type": "JSON", - "path": "https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json" - } + "path": "https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json" }, { "provider": "Deque Systems", "tool": "Axe", - "data": { - "type": "NPM", - "path": "./node_modules/act-rules-implementation-axe-core/report.json" - } + "path": "./node_modules/act-rules-implementation-axe-core/report.json" }, { "provider": "Access42", "tool": "RGAA 3.0", - "data": { - "type": "NPM", - "path": "act-rules-implementation-rgaa/reports/*.json" - } + "path": "act-rules-implementation-rgaa/reports/*.json" } ], "rule-format-metadata": { @@ -232,4 +220,4 @@ "git add" ] } -} +} \ No newline at end of file From 1587ffa8c28a509fe83a17da51f3c898cae7e6ba Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 17 Jun 2019 10:31:56 +0100 Subject: [PATCH 07/20] get and create implementations --- {utils => build}/create-file.js | 0 build/create-implementation-metrics.js | 66 ++++++++++ build/get-implementation.js | 75 ++++++++++++ build/get-implementations-data.js | 113 ------------------ ...t-wcag-sc-metadata.js => get-wcag-data.js} | 8 +- build/implementations/get-framed-report.js | 4 +- ...on.js => get-implementation-for-report.js} | 8 +- build/read-file.js | 5 + gatsby/create-glossary-uages-in-rules.js | 2 +- gatsby/create-testcases-json.js | 2 +- gatsby/create-testcases-of-all-rules.js | 2 +- ...ate-testcases-of-rule-of-em-report-tool.js | 2 +- package.json | 48 +++----- src/pages/rules.js | 8 +- src/templates/coverage.js | 4 +- src/utils/render-fragments.js | 25 +--- 16 files changed, 190 insertions(+), 182 deletions(-) rename {utils => build}/create-file.js (100%) create mode 100644 build/create-implementation-metrics.js create mode 100644 build/get-implementation.js delete mode 100644 build/get-implementations-data.js rename build/{get-wcag-sc-metadata.js => get-wcag-data.js} (96%) rename build/implementations/{get-implementation.js => get-implementation-for-report.js} (75%) create mode 100644 build/read-file.js diff --git a/utils/create-file.js b/build/create-file.js similarity index 100% rename from utils/create-file.js rename to build/create-file.js diff --git a/build/create-implementation-metrics.js b/build/create-implementation-metrics.js new file mode 100644 index 0000000000..6dade4a7e1 --- /dev/null +++ b/build/create-implementation-metrics.js @@ -0,0 +1,66 @@ +const globby = require('globby') +const readFile = require('./read-file') +const createFile = require('./create-file') + +/** + * Init + */ +const init = async () => { + /** + * Get all implementation reports + */ + const reports = globby.sync([`./_data/implementations/*.json`]) + .map(reportPath => { + const fileContent = readFile(reportPath) + return JSON.parse(fileContent) + }) + + /** + * transform data, to be grouped by rule id. + */ + const implementationsGroupedByRuleId = {} + + reports.forEach(report => { + const { tool, organisation, data } = report + + data.forEach(({ ruleId, implementation }) => { + if (!implementation) { + return + } + + /** + * Note: + * only build `metrics` for implementations that are `complete` + */ + const { complete = false } = implementation + if (complete) { + return + } + + if (!implementationsGroupedByRuleId[ruleId]) { + implementationsGroupedByRuleId[ruleId] = [] + } + + implementationsGroupedByRuleId[ruleId].push({ + organisation, + tool, + implementation, + }) + }) + }) + + /** + * Create metrics in `_data` for usage in `site` + */ + await createFile( + `_data/implementation-metrics.json`, + JSON.stringify(implementationsGroupedByRuleId, null, 2) + ) +} + +init() + .then(() => console.info(`Implementation metrics generated.`)) + .catch(e => { + console.error(e) + process.exit(1) + }) diff --git a/build/get-implementation.js b/build/get-implementation.js new file mode 100644 index 0000000000..ab4124e155 --- /dev/null +++ b/build/get-implementation.js @@ -0,0 +1,75 @@ +#!/usr/bin/env node +const assert = require('assert') +const program = require('commander') +const { version } = require('../package.json') +const createFile = require('./create-file') +const getFramedReport = require('./implementations/get-framed-report') +const getImplementationForReport = require('./implementations/get-implementation-for-report') + +/** + * Init + * @param {Object} program program + */ +const init = async (program) => { + const { org, tool, path } = program; + + /** + * assert `args` + */ + assert(org, '`Organisation` is required'); + assert(tool, '`tool` is required'); + assert(path, '`path` is required') + + console.info(`Get implementation of ${tool} by ${org}\n`) + + /** + * fetch `report` & `frame` as required + */ + const framedReport = await getFramedReport(path) + + /** + * Get `implementation` + */ + const data = await getImplementationForReport(framedReport) + + /** + * create report + */ + const report = { + organisation: org, + tool, + data + } + + /** + * Save `implementation` to `_data/implementations` + */ + const filename = tool + .split(' ') + .join('-') + .toLowerCase() + await createFile( + `_data/implementations/${filename}.json`, + JSON.stringify(report, null, 2) + ) +} + +/** + * Parse `args` + */ +program + .version(version) + .option('-o, --org ', 'Organisation, which created the EARL report') + .option('-t, --tool ', 'Tool used by EARL report') + .option('-p, --path ', 'Path to EARL report') + .parse(process.argv); + +/** + * Init + */ +init(program) + .then(() => console.info(`Implementations data generated.`)) + .catch(e => { + console.error(e) + process.exit(1) + }) diff --git a/build/get-implementations-data.js b/build/get-implementations-data.js deleted file mode 100644 index ca68a26c98..0000000000 --- a/build/get-implementations-data.js +++ /dev/null @@ -1,113 +0,0 @@ -const { - config: { implementations }, -} = require('./../package.json') -const getFramedReport = require('./implementations/get-framed-report') -const getImplementation = require('./implementations/get-implementation') -const createFile = require('./../utils/create-file') - -/** - * Create implementation metrics, that can be used in the site, - * for each `implementation` provided as configuration in `package.json`. - */ -const init = async () => { - if (!implementations || !Object.keys(implementations).length) { - throw new Error( - 'No implementations are specified in `config` of `package.json`' - ) - } - - /** - * Collect all implementations from various vendors - */ - const implementationReports = {} - - for (let item of implementations) { - const { provider, tool, path } = item - - console.info(`Get implementation of ${tool} by ${provider}\n`) - - /** - * fetch report & frame as required - */ - const framedReport = await getFramedReport(path) - - /** - * get implementation metrics from report - */ - const implementationStats = await getImplementation(framedReport) - - /** - * create rule based metric - */ - const report = { - tool, - provider, - path, - implementationStats, - } - implementationReports[tool] = report - - /** - * Note: - * These files are only generated for debugging - */ - const filename = tool - .split(' ') - .join('-') - .toLowerCase() - await createFile( - `_data/implementations/${filename}.json`, - JSON.stringify(report, null, 2) - ) - } - - /** - * transform data, to be grouped by rule id. - */ - const groupedMetricByRuleId = {} - - Object.values(implementationReports).forEach(report => { - const { tool, provider, path, implementationStats } = report - - implementationStats.forEach(({ ruleId, implementation }) => { - if (!implementation) { - return - } - - /** - * Note: - * only build metrics for implementations that are `complete` - */ - const { complete = false } = implementation - if (complete) { - return - } - - if (!groupedMetricByRuleId[ruleId]) { - groupedMetricByRuleId[ruleId] = [] - } - - groupedMetricByRuleId[ruleId].push({ - tool, - provider, - path, - implementation, - }) - }) - }) - - /** - * Create metrics in `_data` for usage in `site` - */ - await createFile( - `_data/implementations-metrics.json`, - JSON.stringify(groupedMetricByRuleId, null, 2) - ) -} - -init() - .then(() => console.info(`Implementations data generated.`)) - .catch(err => { - console.error(err) - process.exit(1) - }) diff --git a/build/get-wcag-sc-metadata.js b/build/get-wcag-data.js similarity index 96% rename from build/get-wcag-sc-metadata.js rename to build/get-wcag-data.js index 9b90b16cbc..282ef43fbe 100644 --- a/build/get-wcag-sc-metadata.js +++ b/build/get-wcag-data.js @@ -5,7 +5,7 @@ */ const path = require('path') const axios = require('axios') -const createFile = require('./../utils/create-file') +const createFile = require('./../build/create-file') const pkg = require('./../package.json') const outputFileScMetaData = path.join(__dirname, '..', '_data', 'sc-urls.json') const outputFileScEmReportAuditResult = path.join( @@ -34,12 +34,12 @@ const getMetaData = sc => { is20 ? 'http://www.w3.org/WAI/WCAG20/quickref/#qr-' : 'https://www.w3.org/WAI/WCAG21/quickref/#' - }${path}` + }${path}` const understandingUrl = `${ is20 ? 'http://www.w3.org/TR/UNDERSTANDING-WCAG20/' : 'https://www.w3.org/WAI/WCAG21/Understanding/' - }/${path}.html` + }/${path}.html` /** * Construct `test` - used by `wcag em report tool` */ @@ -73,7 +73,7 @@ const getScMetaData = async url => { return scMetaData } -;(async () => { +(async () => { const wcagReferenceUrl = pkg.config.references.wcag21 if (!wcagReferenceUrl) { throw new Error('No reference URL for WCAG21 is specified in config.') diff --git a/build/implementations/get-framed-report.js b/build/implementations/get-framed-report.js index d6e0b7de11..d25d719058 100644 --- a/build/implementations/get-framed-report.js +++ b/build/implementations/get-framed-report.js @@ -1,9 +1,9 @@ -const fs = require('fs') const globby = require('globby') const axios = require('axios') const jsonld = require('jsonld') const isUrl = require('is-url') const frameConfig = require('./json-ld-frame-config') +const readFile = require('../read-file') const getFramedReport = async path => { if (isUrl(path)) { @@ -13,7 +13,7 @@ const getFramedReport = async path => { const reports = globby.sync([path]) .map(reportPath => { - const fileContent = fs.readFileSync(reportPath, { encoding: 'utf-8' }) + const fileContent = readFile(reportPath) return JSON.parse(fileContent) }) diff --git a/build/implementations/get-implementation.js b/build/implementations/get-implementation-for-report.js similarity index 75% rename from build/implementations/get-implementation.js rename to build/implementations/get-implementation-for-report.js index d10e0edcc4..df1371ca49 100644 --- a/build/implementations/get-implementation.js +++ b/build/implementations/get-implementation-for-report.js @@ -5,10 +5,10 @@ const getRuleMapping = require('./get-rule-mapping') /** * Get implementation metric from submitted report * - * @param {Object|Array} framedReports implementation reports + * @param {Object|Array} reports implementation reports */ -const getImplementation = async framedReports => { - const assertions = getAssertions(framedReports) +const getImplementationForReport = async reports => { + const assertions = getAssertions(reports) const testcasesGroupedByRuleId = await getTestcasesGroupedByRule() return Object.keys(testcasesGroupedByRuleId) @@ -23,4 +23,4 @@ const getImplementation = async framedReports => { .filter(result => result.implementation && result.implementation.length) } -module.exports = getImplementation +module.exports = getImplementationForReport diff --git a/build/read-file.js b/build/read-file.js new file mode 100644 index 0000000000..2e3aa96e42 --- /dev/null +++ b/build/read-file.js @@ -0,0 +1,5 @@ +const fs = require('fs') + +const readFile = (path) => fs.readFileSync(path, { encoding: 'utf-8' }) + +module.exports = readFile \ No newline at end of file diff --git a/gatsby/create-glossary-uages-in-rules.js b/gatsby/create-glossary-uages-in-rules.js index b20c7c0ff1..522cc1a09b 100644 --- a/gatsby/create-glossary-uages-in-rules.js +++ b/gatsby/create-glossary-uages-in-rules.js @@ -5,7 +5,7 @@ */ const queries = require('./queries') const regexps = require('./reg-exps') -const createFile = require('./../utils/create-file') +const createFile = require('./../build/create-file') const getAllMatchesForRegex = require('./get-all-matches-for-regex') const createGlossaryUsagesInRules = options => { diff --git a/gatsby/create-testcases-json.js b/gatsby/create-testcases-json.js index 88af3b90fe..9bb797bd61 100644 --- a/gatsby/create-testcases-json.js +++ b/gatsby/create-testcases-json.js @@ -3,7 +3,7 @@ const { author, description, } = require('./../package.json') -const createFile = require('../utils/create-file') +const createFile = require('../build/create-file') /** * Create `testcases.json` diff --git a/gatsby/create-testcases-of-all-rules.js b/gatsby/create-testcases-of-all-rules.js index ef2a3808bd..f7dd9ac9d2 100644 --- a/gatsby/create-testcases-of-all-rules.js +++ b/gatsby/create-testcases-of-all-rules.js @@ -11,7 +11,7 @@ const fastmatter = require('fastmatter') const { www: { url, baseDir }, } = require('./../package.json') -const createFile = require('../utils/create-file') +const createFile = require('../build/create-file') const getAllMatchesForRegex = require('./get-all-matches-for-regex') const queries = require('./queries') const regexps = require('./reg-exps') diff --git a/gatsby/create-testcases-of-rule-of-em-report-tool.js b/gatsby/create-testcases-of-rule-of-em-report-tool.js index 64fbe582db..14ac771d71 100644 --- a/gatsby/create-testcases-of-rule-of-em-report-tool.js +++ b/gatsby/create-testcases-of-rule-of-em-report-tool.js @@ -6,7 +6,7 @@ const scEmReportAuditResult = require('./../_data/sc-em-report-audit-result.json const graphContext = require('./../_data/wcag-em-report-tool-mappings/@graph-context.json') const graphAdditionalMeta = require('./../_data/wcag-em-report-tool-mappings/@graph-additional-meta.json') const graphEvaluatorMeta = require('./../_data/wcag-em-report-tool-mappings/@graph-evaluator-meta.json') -const createFile = require('../utils/create-file') +const createFile = require('../build/create-file') /** * Create testcases json file that can be used by diff --git a/package.json b/package.json index 999c88e5f7..4c2372fd1c 100644 --- a/package.json +++ b/package.json @@ -82,10 +82,11 @@ } ], "dependencies": { - "act-rules-implementation-rgaa": "git+https://git@github.com/act-rules/act-rules-implementation-rgaa.git", - "act-rules-implementation-axe-core": "git+https://git@github.com/act-rules/act-rules-implementation-axe-core.git", "act-rules-implementation-access-engine": "git+https://git@github.com/act-rules/act-rules-implementation-access-engine.git", + "act-rules-implementation-axe-core": "git+https://git@github.com/act-rules/act-rules-implementation-axe-core.git", + "act-rules-implementation-rgaa": "git+https://git@github.com/act-rules/act-rules-implementation-rgaa.git", "axios": "^0.18.1", + "commander": "^2.20.0", "fastmatter": "^2.1.1", "flat": "^4.1.0", "gatsby": "^2.8.6", @@ -135,17 +136,24 @@ "license": "MIT", "scripts": { "clean": "rm -rf .cache public", - "prebuild": "npm run get-data", + "prebuild": "npm run get:data", "build": "gatsby build", - "develop": "npm run get-data && gatsby develop", + "predevelop": "npm run get:data", + "develop": "gatsby develop", "format": "prettier --write *.{json,md,js,jsx} './{_data,_rules,build,gatsby,pages,src,test-assets}/**/*.{json,md,js,jsx}'", "start": "npm run clean && npm run develop", "serve": "gatsby serve", "test": "npm run test:rules", "test:rules": "jest", - "get-implementations-data": "node ./build/get-implementations-data", - "get-wcag-sc-metadata": "node ./build/get-wcag-sc-metadata", - "get-data": "npm run get-wcag-sc-metadata && npm run get-implementations-data" + "get:implementation:accessEngine": "node ./build/get-implementation --org \"Level Access\" --tool \"Access Engine\" --path \"./node_modules/act-rules-implementation-access-engine/report.json\"", + "get:implementation:alfa": "node ./build/get-implementation --org \"Site Improve\" --tool \"Alfa\" --path \"https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json\"", + "get:implementation:axe": "node ./build/get-implementation --org \"Deque Systems\" --tool \"Axe\" --path \"./node_modules/act-rules-implementation-axe-core/report.json\"", + "get:implementation:rgaa": "node ./build/get-implementation --org \"Access42\" --tool \"RGAA 3.0\" --path $npm_package_config_implementations_rgaa", + "get:implementations": "npm run get:implementation:accessEngine && npm run get:implementation:alfa && npm run get:implementation:axe && npm run get:implementation:rgaa", + "create:implementations:metrics": "node ./build/create-implementation-metrics", + "implementations": "npm run get:implementations && npm run create:implementations:metrics", + "get:wcag:data": "node ./build/get-wcag-data", + "get:data": "npm run get:wcag:data && npm run implementations" }, "homepage": "https://github.com/act-rules/act-rules.github.io", "repository": { @@ -167,28 +175,10 @@ "wcag21": "https://raw.githubusercontent.com/w3c/wai-wcag-quickref/gh-pages/_data/wcag21.json" }, "testcases-url": "https://act-rules.github.io/testcases.json", - "implementations": [ - { - "provider": "Level Access", - "tool": "Access Engine", - "path": "./node_modules/act-rules-implementation-access-engine/report.json" - }, - { - "provider": "Site Improve", - "tool": "Alfa", - "path": "https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json" - }, - { - "provider": "Deque Systems", - "tool": "Axe", - "path": "./node_modules/act-rules-implementation-axe-core/report.json" - }, - { - "provider": "Access42", - "tool": "RGAA 3.0", - "path": "act-rules-implementation-rgaa/reports/*.json" - } - ], + "implementations": { + "axe": "./node_modules/act-rules-implementation-axe-core/report.json", + "rgaa": "./node_modules/act-rules-implementation-rgaa/reports/*.json" + }, "rule-format-metadata": { "input-aspects": { "default": "https://www.w3.org/TR/act-rules-aspects/#intro", diff --git a/src/pages/rules.js b/src/pages/rules.js index 883e9a67b6..0aa033e695 100644 --- a/src/pages/rules.js +++ b/src/pages/rules.js @@ -48,6 +48,10 @@ export default ({ data }) => { accessibility_requirements, 'text' )} + {/* input rules */} + {getInputRulesForRule(input_rules, allRules.edges, true)} + {/* implementation count */} + {getImplementationsCount(slug)} {/* rule description */}
    { }} /> - {/* input rules */} - {getInputRulesForRule(input_rules, allRules.edges, true)} - {/* implementation count */} - {getImplementationsCount(slug)} ) })} diff --git a/src/templates/coverage.js b/src/templates/coverage.js index 6fe54e6202..448bce6c95 100644 --- a/src/templates/coverage.js +++ b/src/templates/coverage.js @@ -33,8 +33,8 @@ export default ({ data }) => { {implementations.map((row, index) => { - const { provider, tool, data } = row - const reportUrl = data.type === `JSON` ? data.path : data.url + const { provider, tool } = row + const reportUrl = `` // todo return ( {index + 1} diff --git a/src/utils/render-fragments.js b/src/utils/render-fragments.js index 7a5346daaf..4140b7afd0 100644 --- a/src/utils/render-fragments.js +++ b/src/utils/render-fragments.js @@ -2,7 +2,7 @@ import React from 'react' import scUrls from './../../_data/sc-urls' import { Link } from 'gatsby' import glossaryUsages from './../../_data/glossary-usages.json' -import implementationMetrics from './../../_data/implementations-metrics.json' +import implementationMetrics from './../../_data/implementation-metrics.json' export const getImplementations = slug => { const ruleId = slug.replace('rules/', '') @@ -18,19 +18,17 @@ export const getImplementations = slug => { - - {metrics.map((metric, index) => { - const { provider, tool, data } = metric - const reportUrl = data.type === `JSON` ? data.path : data.url + {metrics.map(metric => { + const { provider, tool } = metric + const reportUrl =`` return ( - {metrics.map(metric => { - const { provider, tool } = metric - const reportUrl =`` + const { organisation, tool } = metric + const filename = tool + .split(' ') + .join('-') + .toLowerCase() + const reportUrl = `/implementation/${filename}#${ruleId}` return ( - + - + diff --git a/gatsby/get-git-log.js b/utils/get-git-log.js similarity index 100% rename from gatsby/get-git-log.js rename to utils/get-git-log.js From 13b6300042fdef8dc3f1affb25aaf40f8752ffca Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 17 Jun 2019 15:27:59 +0100 Subject: [PATCH 10/20] move glossary gen out of gatsby hook --- build/create-glossary-usages.js | 87 ++++++++++++++++++++++++ gatsby/create-glossary-uages-in-rules.js | 86 ----------------------- gatsby/create-pages.js | 8 --- package.json | 3 +- 4 files changed, 89 insertions(+), 95 deletions(-) create mode 100644 build/create-glossary-usages.js delete mode 100644 gatsby/create-glossary-uages-in-rules.js diff --git a/build/create-glossary-usages.js b/build/create-glossary-usages.js new file mode 100644 index 0000000000..c0e31b91d4 --- /dev/null +++ b/build/create-glossary-usages.js @@ -0,0 +1,87 @@ +/** + * Create glossary usages + * -> for each glossary item (find references in each rule) + * -> this is saved in `_data` which is later used in `pages/glossary` + */ +const globby = require('globby') +const regexps = require('../utils/reg-exps') +const createFile = require('../utils/create-file') +const getAllMatchesForRegex = require('../utils/get-all-matches-for-regex') +const getMarkdownData = require('./../utils/get-markdown-data') + +const init = async () => { + /** + * Get all rules `markdown` data + */ + const rulesData = globby.sync([`./_rules/*.md`]) + .map(rulePath => getMarkdownData(rulePath)) + + + + /** + * Eg: + * { + * `non-empty`: [ + * { name: `aria valid ...`, slug: `rules/XXXXX` }, + * .... + * ] + * .... + * } + */ + const glossaryUsages = {} + + rulesData.forEach(ruleData => { + const { frontmatter, body } = ruleData + const { + id: ruleId, + name: ruleName, + accessibility_requirements: ruleAccessibilityRequirements + } = frontmatter + + const glossaryMatches = getAllMatchesForRegex( + regexps.glossaryReferenceInRules, + body, + false + ) + + glossaryMatches.forEach(glossaryItem => { + const hasGlossaryKey = regexps.glossaryKey.test(glossaryItem.block) + if (!hasGlossaryKey) { + return + } + + const key = glossaryItem.block.match(regexps.glossaryKey)[1] + if (!key) { + return + } + + const usage = { + name: ruleName, + slug: `rules/${ruleId}`, + } + if (!glossaryUsages[key]) { + glossaryUsages[key] = [usage] + return + } + + const exists = glossaryUsages[key].some(u => u.slug === usage.slug) + if (exists) { + return + } + + glossaryUsages[key] = glossaryUsages[key].concat(usage) + }) + }) + + /** + * Create `_data/glossary-usages.json` + */ + await createFile( + `./_data/glossary-usages.json`, + JSON.stringify(glossaryUsages, undefined, 2) + ) +} + +init() + .then(() => console.info(`\nGenerated Glossary Usages Data.\n`)) + .catch(e => console.error(e)) \ No newline at end of file diff --git a/gatsby/create-glossary-uages-in-rules.js b/gatsby/create-glossary-uages-in-rules.js deleted file mode 100644 index c87e40043b..0000000000 --- a/gatsby/create-glossary-uages-in-rules.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Create glossary usages - * -> for each glossary item (find references in each rule) - * -> this is saved in `_data` which is later used in `pages/glossary` - */ -const queries = require('./queries') -const regexps = require('../utils/reg-exps') -const createFile = require('../utils/create-file') -const getAllMatchesForRegex = require('../utils/get-all-matches-for-regex') - -const createGlossaryUsagesInRules = options => { - const { graphql } = options - - return graphql(queries.getAllRules).then(({ errors, data }) => { - if (errors) { - Promise.reject(errors) - } - - /** - * Eg: - * { - * `non-empty`: [ - * { name: `aria valid ...`, slug: `rules/XXXXX` }, - * .... - * ] - * .... - * } - */ - const glossaryUsages = {} - - const getAllRules = data.allMarkdownRemark.edges - - getAllRules.forEach(async markdownPage => { - const { node } = markdownPage - const { rawMarkdownBody, frontmatter, fields } = node - const { name } = frontmatter - const { slug } = fields - - const glossaryMatches = getAllMatchesForRegex( - regexps.glossaryReferenceInRules, - rawMarkdownBody, - false - ) - - glossaryMatches.forEach(glossaryItem => { - const hasGlossaryKey = regexps.glossaryKey.test(glossaryItem.block) - if (!hasGlossaryKey) { - return - } - - const key = glossaryItem.block.match(regexps.glossaryKey)[1] - if (!key) { - return - } - - const usage = { - name, - slug, - } - if (!glossaryUsages[key]) { - glossaryUsages[key] = [usage] - return - } - - const exists = glossaryUsages[key].some(u => u.slug === usage.slug) - if (exists) { - return - } - - glossaryUsages[key] = glossaryUsages[key].concat(usage) - }) - }) - - /** - * Create `_data/glossay-usages.json` - */ - createFile( - `./_data/glossary-usages.json`, - JSON.stringify(glossaryUsages, undefined, 2) - ) - - console.info(`\nGenerated Glossary Usages Data.\n`) - }) -} - -module.exports = createGlossaryUsagesInRules diff --git a/gatsby/create-pages.js b/gatsby/create-pages.js index 75548bbe85..9132a2be94 100644 --- a/gatsby/create-pages.js +++ b/gatsby/create-pages.js @@ -1,5 +1,4 @@ const createPageAddMdContext = require('./create-page-add-md-context') -const createGlossaryUsagesInRules = require('./create-glossary-uages-in-rules') const createPageImplementerReport = require('./create-page-implementer-report') const createPages = async options => { @@ -11,13 +10,6 @@ const createPages = async options => { */ createPageAddMdContext(options), - /** - * Create glossary usages - * -> for each glossary item (find references in each rule) - * -> this is saved in `_data` which is later used in `pages/glossary` - */ - createGlossaryUsagesInRules(options), - /** * Create implementation report pages */ diff --git a/package.json b/package.json index bc3df5b245..7909c0906a 100644 --- a/package.json +++ b/package.json @@ -153,8 +153,9 @@ "create:implementations:metrics": "node ./build/create-implementation-metrics", "implementations": "npm run get:implementations && npm run create:implementations:metrics", "create:testcases": "node ./build/create-testcases", + "create:glossary": "node ./build/create-glossary-usages", "get:wcag:data": "node ./build/get-wcag-data", - "get:data": "npm run get:wcag:data && npm run create:testcases && npm run implementations" + "get:data": "npm run get:wcag:data && npm run create:testcases && npm run create:glossary && npm run implementations" }, "homepage": "https://github.com/act-rules/act-rules.github.io", "repository": { From 559861e0f4ffe0cf785130525c5e8152fcd33f55 Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 17 Jun 2019 15:28:47 +0100 Subject: [PATCH 11/20] run prettier --- build/create-glossary-usages.js | 9 +- build/create-implementation-metrics.js | 121 ++++++++-------- build/create-testcases.js | 17 +-- build/get-implementation.js | 92 ++++++------ build/get-wcag-data.js | 6 +- build/implementations/get-framed-report.js | 11 +- build/implementations/get-rule-mapping.js | 7 +- .../get-testcases-grouped-by-rule.js | 2 +- gatsby/create-page-implementer-report.js | 50 +++---- gatsby/create-pages.js | 2 +- gatsby/get-template.js | 2 +- package.json | 2 +- pages/implementations/wcag-em-tool.md | 8 +- src/templates/implementations.js | 4 +- src/templates/implementer.js | 136 +++++++++--------- src/utils/render-fragments.js | 4 +- 16 files changed, 230 insertions(+), 243 deletions(-) diff --git a/build/create-glossary-usages.js b/build/create-glossary-usages.js index c0e31b91d4..da851a13c5 100644 --- a/build/create-glossary-usages.js +++ b/build/create-glossary-usages.js @@ -13,11 +13,10 @@ const init = async () => { /** * Get all rules `markdown` data */ - const rulesData = globby.sync([`./_rules/*.md`]) + const rulesData = globby + .sync([`./_rules/*.md`]) .map(rulePath => getMarkdownData(rulePath)) - - /** * Eg: * { @@ -35,7 +34,7 @@ const init = async () => { const { id: ruleId, name: ruleName, - accessibility_requirements: ruleAccessibilityRequirements + accessibility_requirements: ruleAccessibilityRequirements, } = frontmatter const glossaryMatches = getAllMatchesForRegex( @@ -84,4 +83,4 @@ const init = async () => { init() .then(() => console.info(`\nGenerated Glossary Usages Data.\n`)) - .catch(e => console.error(e)) \ No newline at end of file + .catch(e => console.error(e)) diff --git a/build/create-implementation-metrics.js b/build/create-implementation-metrics.js index ea01a99111..eba6cf360a 100644 --- a/build/create-implementation-metrics.js +++ b/build/create-implementation-metrics.js @@ -6,75 +6,76 @@ const createFile = require('../utils/create-file') * Init */ const init = async () => { - /** - * Get all implementation reports - */ - const reports = globby.sync([`./_data/implementations/*.json`]) - .map(reportPath => { - const fileContent = readFile(reportPath) - return JSON.parse(fileContent) - }) + /** + * Get all implementation reports + */ + const reports = globby + .sync([`./_data/implementations/*.json`]) + .map(reportPath => { + const fileContent = readFile(reportPath) + return JSON.parse(fileContent) + }) - const implementers = [] - const implementationsGroupedByRuleId = {} + const implementers = [] + const implementationsGroupedByRuleId = {} - reports.forEach(report => { - const { tool, organisation, data } = report + reports.forEach(report => { + const { tool, organisation, data } = report - /** - * Create data that can be used in `src/templates/coverage.js` - */ - implementers.push(report) + /** + * Create data that can be used in `src/templates/coverage.js` + */ + implementers.push(report) - /** - * Iterate each implementation & group by rule id - */ - data.forEach(({ ruleId, implementation }) => { - if (!implementation) { - return - } + /** + * Iterate each implementation & group by rule id + */ + data.forEach(({ ruleId, implementation }) => { + if (!implementation) { + return + } - /** - * Note: - * only build `metrics` for implementations that are `complete` - */ - const { complete = false } = implementation - if (complete) { - return - } + /** + * Note: + * only build `metrics` for implementations that are `complete` + */ + const { complete = false } = implementation + if (complete) { + return + } - if (!implementationsGroupedByRuleId[ruleId]) { - implementationsGroupedByRuleId[ruleId] = [] - } + if (!implementationsGroupedByRuleId[ruleId]) { + implementationsGroupedByRuleId[ruleId] = [] + } - implementationsGroupedByRuleId[ruleId].push({ - organisation, - tool, - implementation, - }) - }) - }) + implementationsGroupedByRuleId[ruleId].push({ + organisation, + tool, + implementation, + }) + }) + }) - /** - * Create `implementations.json` - */ - await createFile( - `_data/implementers.json`, - JSON.stringify(implementers, null, 2) - ) + /** + * Create `implementations.json` + */ + await createFile( + `_data/implementers.json`, + JSON.stringify(implementers, null, 2) + ) - /** - * Create metrics in `_data` for usage in `site` - */ - await createFile( - `_data/implementation-metrics.json`, - JSON.stringify(implementationsGroupedByRuleId, null, 2) - ) + /** + * Create metrics in `_data` for usage in `site` + */ + await createFile( + `_data/implementation-metrics.json`, + JSON.stringify(implementationsGroupedByRuleId, null, 2) + ) } init() - .then(() => console.info(`\nImplementation metrics generated.\n`)) - .catch(e => { - console.error(e) - process.exit(1) - }) + .then(() => console.info(`\nImplementation metrics generated.\n`)) + .catch(e => { + console.error(e) + process.exit(1) + }) diff --git a/build/create-testcases.js b/build/create-testcases.js index 50932663c3..5bb1fd4ede 100644 --- a/build/create-testcases.js +++ b/build/create-testcases.js @@ -1,4 +1,3 @@ - const globby = require('globby') const makeDir = require('make-dir') const objectHash = require('object-hash') @@ -16,7 +15,7 @@ const createTestcasesOfRuleOfEmReportTool = require('./testcases/create-testcase /** * Create test case files & other meta-data from test case in each rule. - * + * * -> create test cases files into `./public/testcases/` * -> copy `./test-assets/*` into `./public` * -> create `testcases.json` into `./public` @@ -30,10 +29,10 @@ const init = async () => { /** * Get all rules `markdown` data */ - const rulesData = globby.sync([`./_rules/*.md`]) + const rulesData = globby + .sync([`./_rules/*.md`]) .map(rulePath => getMarkdownData(rulePath)) - let allRulesTestcases = [] /** @@ -46,12 +45,9 @@ const init = async () => { const { id: ruleId, name: ruleName, - accessibility_requirements: ruleAccessibilityRequirements + accessibility_requirements: ruleAccessibilityRequirements, } = frontmatter - const codeTitles = getAllMatchesForRegex( - regexps.testcaseTitle, - body - ) + const codeTitles = getAllMatchesForRegex(regexps.testcaseTitle, body) /** * get code blocks in markdown body @@ -139,7 +135,6 @@ const init = async () => { await createTestcasesJson(allRulesTestcases) console.info(`\nGenerated Test Cases.\n`) - } /** @@ -150,4 +145,4 @@ init() .catch(e => { console.error(e) process.write(1) - }) \ No newline at end of file + }) diff --git a/build/get-implementation.js b/build/get-implementation.js index c5133e48fb..4aae3970a1 100644 --- a/build/get-implementation.js +++ b/build/get-implementation.js @@ -9,66 +9,66 @@ const getImplementationForReport = require('./implementations/get-implementation * Init * @param {Object} program program */ -const init = async (program) => { - const { org, tool, path } = program; +const init = async program => { + const { org, tool, path } = program - /** - * assert `args` - */ - assert(org, '`Organisation` is required'); - assert(tool, '`tool` is required'); - assert(path, '`path` is required') + /** + * assert `args` + */ + assert(org, '`Organisation` is required') + assert(tool, '`tool` is required') + assert(path, '`path` is required') - console.info(`\nGet implementation of ${tool} by ${org}\n`) + console.info(`\nGet implementation of ${tool} by ${org}\n`) - /** - * fetch `report` & `frame` as required - */ - const framedReport = await getFramedReport(path) + /** + * fetch `report` & `frame` as required + */ + const framedReport = await getFramedReport(path) - /** - * Get `implementation` - */ - const data = await getImplementationForReport(framedReport) + /** + * Get `implementation` + */ + const data = await getImplementationForReport(framedReport) - /** - * create report - */ - const report = { - organisation: org, - tool, - data - } + /** + * create report + */ + const report = { + organisation: org, + tool, + data, + } - /** - * Save `implementation` to `_data/implementations` - */ - const filename = tool - .split(' ') - .join('-') - .toLowerCase() - await createFile( - `_data/implementations/${filename}.json`, - JSON.stringify(report, null, 2) - ) + /** + * Save `implementation` to `_data/implementations` + */ + const filename = tool + .split(' ') + .join('-') + .toLowerCase() + await createFile( + `_data/implementations/${filename}.json`, + JSON.stringify(report, null, 2) + ) } /** * Parse `args` */ program - .version(version) - .option('-o, --org ', 'Organisation, which created the EARL report') - .option('-t, --tool ', 'Tool used by EARL report') - .option('-p, --path ', 'Path to EARL report') - .parse(process.argv); + .version(version) + .option('-o, --org ', 'Organisation, which created the EARL report') + .option('-t, --tool ', 'Tool used by EARL report') + .option('-p, --path ', 'Path to EARL report') + .parse(process.argv) /** * Init */ init(program) - .then(() => console.info(`\nImplementations data generated.\n`)) - .catch(e => { - console.error(e) - process.exit(1) - }) + .then(() => console.info(`\nImplementations data generated.\n`)) + .catch(e => { + console.error(e) + process.exit(1) + }) diff --git a/build/get-wcag-data.js b/build/get-wcag-data.js index d0c2189b45..8e61fc89bb 100644 --- a/build/get-wcag-data.js +++ b/build/get-wcag-data.js @@ -34,12 +34,12 @@ const getMetaData = sc => { is20 ? 'http://www.w3.org/WAI/WCAG20/quickref/#qr-' : 'https://www.w3.org/WAI/WCAG21/quickref/#' - }${path}` + }${path}` const understandingUrl = `${ is20 ? 'http://www.w3.org/TR/UNDERSTANDING-WCAG20/' : 'https://www.w3.org/WAI/WCAG21/Understanding/' - }/${path}.html` + }/${path}.html` /** * Construct `test` - used by `wcag em report tool` */ @@ -73,7 +73,7 @@ const getScMetaData = async url => { return scMetaData } -(async () => { +;(async () => { const wcagReferenceUrl = pkg.config.references.wcag21 if (!wcagReferenceUrl) { throw new Error('No reference URL for WCAG21 is specified in config.') diff --git a/build/implementations/get-framed-report.js b/build/implementations/get-framed-report.js index f1107a8953..af1acdaa72 100644 --- a/build/implementations/get-framed-report.js +++ b/build/implementations/get-framed-report.js @@ -11,11 +11,10 @@ const getFramedReport = async path => { return await jsonld.frame(data, frameConfig) } - const reports = globby.sync([path]) - .map(reportPath => { - const fileContent = readFile(reportPath) - return JSON.parse(fileContent) - }) + const reports = globby.sync([path]).map(reportPath => { + const fileContent = readFile(reportPath) + return JSON.parse(fileContent) + }) const result = [] @@ -27,4 +26,4 @@ const getFramedReport = async path => { return result } -module.exports = getFramedReport \ No newline at end of file +module.exports = getFramedReport diff --git a/build/implementations/get-rule-mapping.js b/build/implementations/get-rule-mapping.js index 76979db625..159ce5e3f6 100644 --- a/build/implementations/get-rule-mapping.js +++ b/build/implementations/get-rule-mapping.js @@ -31,10 +31,9 @@ function getRuleMapping(testcases, assertions) { // Push untested results for every test case without an assertion Object.values(ruleData).forEach(testMappings => { if ( - !Object.values(testMappings) - .some(({ url }) => - url && url.includes(relativeUrl) - ) + !Object.values(testMappings).some( + ({ url }) => url && url.includes(relativeUrl) + ) ) { testMappings.push({ title: testMappings[0].title, diff --git a/build/implementations/get-testcases-grouped-by-rule.js b/build/implementations/get-testcases-grouped-by-rule.js index 3690ebff85..2d7878be70 100644 --- a/build/implementations/get-testcases-grouped-by-rule.js +++ b/build/implementations/get-testcases-grouped-by-rule.js @@ -6,7 +6,7 @@ const testcasesData = require('./../../public/testcases.json') */ const getTestcasesGroupedByRule = () => { const { testcases } = testcasesData - + return testcases.reduce((out, testcase) => { const { ruleId } = testcase if (!out[ruleId]) { diff --git a/gatsby/create-page-implementer-report.js b/gatsby/create-page-implementer-report.js index 43a6845df8..59ba87a003 100644 --- a/gatsby/create-page-implementer-report.js +++ b/gatsby/create-page-implementer-report.js @@ -1,34 +1,34 @@ -const implementers = require('../_data/implementers.json'); +const implementers = require('../_data/implementers.json') const getTemplate = require('./get-template') -const createPageImplementerReport = (options) => { - const { actions } = options - const { createPage } = actions +const createPageImplementerReport = options => { + const { actions } = options + const { createPage } = actions - // Your component that should be rendered for every item in JSON. + // Your component that should be rendered for every item in JSON. - // Create pages for each JSON entry. - implementers.forEach(implementer => { - const { tool, organisation } = implementer + // Create pages for each JSON entry. + implementers.forEach(implementer => { + const { tool, organisation } = implementer - const filename = tool - .split(' ') - .join('-') - .toLowerCase() + const filename = tool + .split(' ') + .join('-') + .toLowerCase() - const slug = `implementation/${filename}`; + const slug = `implementation/${filename}` - createPage({ - path: slug, - component: getTemplate('implementer'), - context: { - slug, - filename, - title: `Implementation Report of ${tool} (${organisation})`, - data: JSON.stringify(implementer) - } - }); - }); + createPage({ + path: slug, + component: getTemplate('implementer'), + context: { + slug, + filename, + title: `Implementation Report of ${tool} (${organisation})`, + data: JSON.stringify(implementer), + }, + }) + }) } -module.exports = createPageImplementerReport \ No newline at end of file +module.exports = createPageImplementerReport diff --git a/gatsby/create-pages.js b/gatsby/create-pages.js index 9132a2be94..77a7ae3a07 100644 --- a/gatsby/create-pages.js +++ b/gatsby/create-pages.js @@ -13,7 +13,7 @@ const createPages = async options => { /** * Create implementation report pages */ - createPageImplementerReport(options) + createPageImplementerReport(options), ] await Promise.all(promises) diff --git a/gatsby/get-template.js b/gatsby/get-template.js index c567fac561..db3c61a182 100644 --- a/gatsby/get-template.js +++ b/gatsby/get-template.js @@ -4,7 +4,7 @@ const getTemplate = (type, slug) => { const map = { glossary: './src/templates/glossary.js', rules: './src/templates/rule.js', - implementer: './src/templates/implementer.js' + implementer: './src/templates/implementer.js', } if (Object.keys(map).includes(type)) { diff --git a/package.json b/package.json index 7909c0906a..2a48b4c489 100644 --- a/package.json +++ b/package.json @@ -212,4 +212,4 @@ "git add" ] } -} \ No newline at end of file +} diff --git a/pages/implementations/wcag-em-tool.md b/pages/implementations/wcag-em-tool.md index 1cdee7ee5d..87bd5c4b71 100644 --- a/pages/implementations/wcag-em-tool.md +++ b/pages/implementations/wcag-em-tool.md @@ -22,11 +22,11 @@ If you have a manual test methodology, where you fill results into some report t ## Step 3: Run The Testcases -1. Under each success criterion set to "Cannot tell" click "Show web pages to enter -individual results +1. Under each success criterion set to "Cannot tell" click "Show web pages to enter + individual results -2. For every page, answer "passed", "failed" "not present" or "cannot tell" (this has to be -done on each success criterion +2. For every page, answer "passed", "failed" "not present" or "cannot tell" (this has to be + done on each success criterion 3. Go to "report findings" and enter your name under "evaluator" diff --git a/src/templates/implementations.js b/src/templates/implementations.js index d77a3f57b6..a3c6056bd8 100644 --- a/src/templates/implementations.js +++ b/src/templates/implementations.js @@ -41,9 +41,7 @@ export default ({ data }) => { {/* */} ) diff --git a/src/templates/implementer.js b/src/templates/implementer.js index 8035e1caa8..a81dc79658 100644 --- a/src/templates/implementer.js +++ b/src/templates/implementer.js @@ -4,80 +4,78 @@ import { graphql } from 'gatsby' import SEO from '../components/seo' export default ({ data }) => { - const { site, sitePage } = data - const { context } = sitePage - const { title: pageTitle, data: contextData } = context + const { site, sitePage } = data + const { context } = sitePage + const { title: pageTitle, data: contextData } = context - const updatedTitle = `${pageTitle} | ${site.siteMetadata.title}` - const report = JSON.parse(contextData) - const { data: ruleImplementations } = report + const updatedTitle = `${pageTitle} | ${site.siteMetadata.title}` + const report = JSON.parse(contextData) + const { data: ruleImplementations } = report - return ( - - -
    -

    {pageTitle}

    - { - ruleImplementations.map((ruleImplementation, index) => { - const { ruleId, ruleName, implementation } = ruleImplementation - const { assertions } = implementation[0]; - const key = `${index}-${ruleId}` - return ( -
    # Tool Name Created By Report
    {index + 1} {tool} {provider} @@ -438,20 +436,7 @@ export function getImplementationsCount(slug) { return (
    -

    Implementations ({metrics.length})

    -
      - {metrics.map((metric, index) => { - const { provider, tool, data } = metric - const reportUrl = data.type === `JSON` ? data.path : data.url - return ( -
    • - - {tool} ({provider}) - -
    • - ) - })} -
    +

    Implementations: {metrics.length}

    ) From 9d2410df38d9271fec6dbecda7a8e41afbfcfc53 Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 17 Jun 2019 11:42:27 +0100 Subject: [PATCH 08/20] generate testcases outside gatsby hook --- build/create-implementation-metrics.js | 6 +- build/create-testcases.js | 153 ++++++++++++++++++ build/get-implementation.js | 7 +- build/get-wcag-data.js | 4 +- build/implementations/get-framed-report.js | 2 +- .../testcases}/copy-testcases-assets.js | 2 +- .../testcases}/create-testcases-json.js | 4 +- ...ate-testcases-of-rule-of-em-report-tool.js | 14 +- .../@graph-additional-meta.json | 0 .../@graph-context.json | 0 .../@graph-evaluator-meta.json | 0 gatsby/create-glossary-uages-in-rules.js | 8 +- gatsby/create-pages.js | 9 -- gatsby/create-testcases-of-all-rules.js | 139 ---------------- package.json | 3 +- src/templates/coverage.js | 6 +- src/templates/rule.js | 1 + test/utils/get-rules-data.js | 15 +- {build => utils}/create-file.js | 0 .../get-all-matches-for-regex.js | 7 + utils/get-markdown-data.js | 16 ++ {build => utils}/read-file.js | 0 {gatsby => utils}/reg-exps.js | 0 23 files changed, 206 insertions(+), 190 deletions(-) create mode 100644 build/create-testcases.js rename {gatsby => build/testcases}/copy-testcases-assets.js (83%) rename {gatsby => build/testcases}/create-testcases-json.js (83%) rename {gatsby => build/testcases}/create-testcases-of-rule-of-em-report-tool.js (78%) rename {_data => build/testcases}/wcag-em-report-tool-mappings/@graph-additional-meta.json (100%) rename {_data => build/testcases}/wcag-em-report-tool-mappings/@graph-context.json (100%) rename {_data => build/testcases}/wcag-em-report-tool-mappings/@graph-evaluator-meta.json (100%) delete mode 100644 gatsby/create-testcases-of-all-rules.js rename {build => utils}/create-file.js (100%) rename {gatsby => utils}/get-all-matches-for-regex.js (71%) create mode 100644 utils/get-markdown-data.js rename {build => utils}/read-file.js (100%) rename {gatsby => utils}/reg-exps.js (100%) diff --git a/build/create-implementation-metrics.js b/build/create-implementation-metrics.js index 6dade4a7e1..fe1976c61e 100644 --- a/build/create-implementation-metrics.js +++ b/build/create-implementation-metrics.js @@ -1,6 +1,6 @@ const globby = require('globby') -const readFile = require('./read-file') -const createFile = require('./create-file') +const readFile = require('../utils/read-file') +const createFile = require('../utils/create-file') /** * Init @@ -59,7 +59,7 @@ const init = async () => { } init() - .then(() => console.info(`Implementation metrics generated.`)) + .then(() => console.info(`\nImplementation metrics generated.\n`)) .catch(e => { console.error(e) process.exit(1) diff --git a/build/create-testcases.js b/build/create-testcases.js new file mode 100644 index 0000000000..50932663c3 --- /dev/null +++ b/build/create-testcases.js @@ -0,0 +1,153 @@ + +const globby = require('globby') +const makeDir = require('make-dir') +const objectHash = require('object-hash') +const codeBlocks = require('gfm-code-blocks') +const { + www: { url, baseDir }, +} = require('./../package.json') +const getMarkdownData = require('./../utils/get-markdown-data') +const createFile = require('../utils/create-file') +const regexps = require('../utils/reg-exps') +const getAllMatchesForRegex = require('../utils/get-all-matches-for-regex') +const copyTestcasesAssets = require('./testcases/copy-testcases-assets') +const createTestcasesJson = require('./testcases/create-testcases-json') +const createTestcasesOfRuleOfEmReportTool = require('./testcases/create-testcases-of-rule-of-em-report-tool') + +/** + * Create test case files & other meta-data from test case in each rule. + * + * -> create test cases files into `./public/testcases/` + * -> copy `./test-assets/*` into `./public` + * -> create `testcases.json` into `./public` + */ +const init = async () => { + /** + * Create `public` directory + */ + await makeDir(`public`) + + /** + * Get all rules `markdown` data + */ + const rulesData = globby.sync([`./_rules/*.md`]) + .map(rulePath => getMarkdownData(rulePath)) + + + let allRulesTestcases = [] + + /** + * iterate all rule pages + * -> get code snippets + * -> and their relevant titles + */ + rulesData.forEach(ruleData => { + const { frontmatter, body } = ruleData + const { + id: ruleId, + name: ruleName, + accessibility_requirements: ruleAccessibilityRequirements + } = frontmatter + const codeTitles = getAllMatchesForRegex( + regexps.testcaseTitle, + body + ) + + /** + * get code blocks in markdown body + */ + const codeSnippets = codeBlocks(body) + + if (codeTitles.length !== codeSnippets.length) { + throw new Error( + `Number of matching titles for code snippets is wrong. Check markdown '${ruleName}' for irregularities.` + ) + } + + /** + * iterate each code snippet + * -> create a testcase file + * -> and add meta of testcase to `testcases.json` + */ + const ruleTestcases = codeSnippets.reduce((out, codeBlock, index) => { + const title = codeTitles[index] + if (!title) { + throw new Error('No title found for code snippet.') + } + + const { code, block } = codeBlock + let { type = 'html' } = codeBlock + + if (regexps.testcaseCodeSnippetTypeIsSvg.test(block.substring(0, 15))) { + type = 'svg' + } + + const codeId = objectHash({ + block, + type, + ruleId, + }) + + const titleCurated = title.value.split(' ').map(t => t.toLowerCase()) + + const testcaseFileName = `${ruleId}/${codeId}.${type}` + const testcasePath = `testcases/${testcaseFileName}` + /** + * Create testcase file + */ + createFile(`${baseDir}/${testcasePath}`, code) + + /** + * Create meta data for testcase(s) + */ + const testcase = { + testcaseId: codeId, + url: `${url}/${testcasePath}`, + expected: titleCurated[0], + ruleId, + ruleName, + rulePage: `${url}/rules/${ruleId}`, + ruleAccessibilityRequirements, + } + + out.push(testcase) + return out + }, []) + + // add rule testcases to all testcases + allRulesTestcases = allRulesTestcases.concat(ruleTestcases) + + /** + * Create test cases of rule for use with `em report tool` + */ + createTestcasesOfRuleOfEmReportTool({ + ruleId, + ruleName, + ruleTestcases, + ruleAccessibilityRequirements, + }) + }) + + /** + * Copy `test-assets` that are used by `testcases` + */ + await copyTestcasesAssets() + + /** + * Generate `testcases.json` + */ + await createTestcasesJson(allRulesTestcases) + + console.info(`\nGenerated Test Cases.\n`) + +} + +/** + * Invoke + */ +init() + .then(`Created testcases`) + .catch(e => { + console.error(e) + process.write(1) + }) \ No newline at end of file diff --git a/build/get-implementation.js b/build/get-implementation.js index ab4124e155..c5133e48fb 100644 --- a/build/get-implementation.js +++ b/build/get-implementation.js @@ -1,8 +1,7 @@ -#!/usr/bin/env node const assert = require('assert') const program = require('commander') const { version } = require('../package.json') -const createFile = require('./create-file') +const createFile = require('../utils/create-file') const getFramedReport = require('./implementations/get-framed-report') const getImplementationForReport = require('./implementations/get-implementation-for-report') @@ -20,7 +19,7 @@ const init = async (program) => { assert(tool, '`tool` is required'); assert(path, '`path` is required') - console.info(`Get implementation of ${tool} by ${org}\n`) + console.info(`\nGet implementation of ${tool} by ${org}\n`) /** * fetch `report` & `frame` as required @@ -68,7 +67,7 @@ program * Init */ init(program) - .then(() => console.info(`Implementations data generated.`)) + .then(() => console.info(`\nImplementations data generated.\n`)) .catch(e => { console.error(e) process.exit(1) diff --git a/build/get-wcag-data.js b/build/get-wcag-data.js index 282ef43fbe..d0c2189b45 100644 --- a/build/get-wcag-data.js +++ b/build/get-wcag-data.js @@ -5,7 +5,7 @@ */ const path = require('path') const axios = require('axios') -const createFile = require('./../build/create-file') +const createFile = require('../utils/create-file') const pkg = require('./../package.json') const outputFileScMetaData = path.join(__dirname, '..', '_data', 'sc-urls.json') const outputFileScEmReportAuditResult = path.join( @@ -111,5 +111,5 @@ const getScMetaData = async url => { JSON.stringify(scEmReportAuditResult, undefined, 2) ) - console.info('\nDONE!!! Generated WCAG Success Criterion Data.\n') + console.info('\nGenerated WCAG Success Criterion Data.\n') })() diff --git a/build/implementations/get-framed-report.js b/build/implementations/get-framed-report.js index d25d719058..f1107a8953 100644 --- a/build/implementations/get-framed-report.js +++ b/build/implementations/get-framed-report.js @@ -3,7 +3,7 @@ const axios = require('axios') const jsonld = require('jsonld') const isUrl = require('is-url') const frameConfig = require('./json-ld-frame-config') -const readFile = require('../read-file') +const readFile = require('../../utils/read-file') const getFramedReport = async path => { if (isUrl(path)) { diff --git a/gatsby/copy-testcases-assets.js b/build/testcases/copy-testcases-assets.js similarity index 83% rename from gatsby/copy-testcases-assets.js rename to build/testcases/copy-testcases-assets.js index c1417d97cf..874b9b3d4d 100644 --- a/gatsby/copy-testcases-assets.js +++ b/build/testcases/copy-testcases-assets.js @@ -6,7 +6,7 @@ const { ncp } = require('ncp') const copyTestcasesAssets = () => { return new Promise((resolve, reject) => { ncp('./test-assets', './public/test-assets', err => { - console.info(`\nDONE!!! Copied Test Assets Directory.\n`) + console.info(`\nCopied Test Assets Directory.\n`) if (err) { reject(err) } diff --git a/gatsby/create-testcases-json.js b/build/testcases/create-testcases-json.js similarity index 83% rename from gatsby/create-testcases-json.js rename to build/testcases/create-testcases-json.js index 9bb797bd61..3cf1f35958 100644 --- a/gatsby/create-testcases-json.js +++ b/build/testcases/create-testcases-json.js @@ -2,8 +2,8 @@ const { www: { url, baseDir }, author, description, -} = require('./../package.json') -const createFile = require('../build/create-file') +} = require('./../../package.json') +const createFile = require('../../utils/create-file') /** * Create `testcases.json` diff --git a/gatsby/create-testcases-of-rule-of-em-report-tool.js b/build/testcases/create-testcases-of-rule-of-em-report-tool.js similarity index 78% rename from gatsby/create-testcases-of-rule-of-em-report-tool.js rename to build/testcases/create-testcases-of-rule-of-em-report-tool.js index 14ac771d71..34d73a0d92 100644 --- a/gatsby/create-testcases-of-rule-of-em-report-tool.js +++ b/build/testcases/create-testcases-of-rule-of-em-report-tool.js @@ -1,12 +1,12 @@ const { www: { url, baseDir }, -} = require('./../package.json') -const scUrlsMetaData = require('./../_data/sc-urls.json') -const scEmReportAuditResult = require('./../_data/sc-em-report-audit-result.json') -const graphContext = require('./../_data/wcag-em-report-tool-mappings/@graph-context.json') -const graphAdditionalMeta = require('./../_data/wcag-em-report-tool-mappings/@graph-additional-meta.json') -const graphEvaluatorMeta = require('./../_data/wcag-em-report-tool-mappings/@graph-evaluator-meta.json') -const createFile = require('../build/create-file') +} = require('./../../package.json') +const scUrlsMetaData = require('./../../_data/sc-urls.json') +const scEmReportAuditResult = require('./../../_data/sc-em-report-audit-result.json') +const graphContext = require('./wcag-em-report-tool-mappings/@graph-context.json') +const graphAdditionalMeta = require('./wcag-em-report-tool-mappings/@graph-additional-meta.json') +const graphEvaluatorMeta = require('./wcag-em-report-tool-mappings/@graph-evaluator-meta.json') +const createFile = require('../../utils/create-file') /** * Create testcases json file that can be used by diff --git a/_data/wcag-em-report-tool-mappings/@graph-additional-meta.json b/build/testcases/wcag-em-report-tool-mappings/@graph-additional-meta.json similarity index 100% rename from _data/wcag-em-report-tool-mappings/@graph-additional-meta.json rename to build/testcases/wcag-em-report-tool-mappings/@graph-additional-meta.json diff --git a/_data/wcag-em-report-tool-mappings/@graph-context.json b/build/testcases/wcag-em-report-tool-mappings/@graph-context.json similarity index 100% rename from _data/wcag-em-report-tool-mappings/@graph-context.json rename to build/testcases/wcag-em-report-tool-mappings/@graph-context.json diff --git a/_data/wcag-em-report-tool-mappings/@graph-evaluator-meta.json b/build/testcases/wcag-em-report-tool-mappings/@graph-evaluator-meta.json similarity index 100% rename from _data/wcag-em-report-tool-mappings/@graph-evaluator-meta.json rename to build/testcases/wcag-em-report-tool-mappings/@graph-evaluator-meta.json diff --git a/gatsby/create-glossary-uages-in-rules.js b/gatsby/create-glossary-uages-in-rules.js index 522cc1a09b..c87e40043b 100644 --- a/gatsby/create-glossary-uages-in-rules.js +++ b/gatsby/create-glossary-uages-in-rules.js @@ -4,9 +4,9 @@ * -> this is saved in `_data` which is later used in `pages/glossary` */ const queries = require('./queries') -const regexps = require('./reg-exps') -const createFile = require('./../build/create-file') -const getAllMatchesForRegex = require('./get-all-matches-for-regex') +const regexps = require('../utils/reg-exps') +const createFile = require('../utils/create-file') +const getAllMatchesForRegex = require('../utils/get-all-matches-for-regex') const createGlossaryUsagesInRules = options => { const { graphql } = options @@ -79,7 +79,7 @@ const createGlossaryUsagesInRules = options => { JSON.stringify(glossaryUsages, undefined, 2) ) - console.info(`\nDONE!!! Generated Glossary Usages Data.\n`) + console.info(`\nGenerated Glossary Usages Data.\n`) }) } diff --git a/gatsby/create-pages.js b/gatsby/create-pages.js index a0cf3fae8b..ea9cdab5f1 100644 --- a/gatsby/create-pages.js +++ b/gatsby/create-pages.js @@ -1,5 +1,4 @@ const createPageAddMdContext = require('./create-page-add-md-context') -const createTestcasesOfAllRules = require('./create-testcases-of-all-rules') const createGlossaryUsagesInRules = require('./create-glossary-uages-in-rules') const createPages = async options => { @@ -11,14 +10,6 @@ const createPages = async options => { */ createPageAddMdContext(options), - /** - * Create test case files & meta data - * -> create test cases files into `./public/testcases/` - * -> copy `./test-assets/*` into `./public` - * -> create `testcases.json` into `./public` - */ - createTestcasesOfAllRules(options), - /** * Create glossary usages * -> for each glossary item (find references in each rule) diff --git a/gatsby/create-testcases-of-all-rules.js b/gatsby/create-testcases-of-all-rules.js deleted file mode 100644 index f7dd9ac9d2..0000000000 --- a/gatsby/create-testcases-of-all-rules.js +++ /dev/null @@ -1,139 +0,0 @@ -/** - * Create test case files & meta data - * -> create test cases files into `./public/testcases/` - * -> copy `./test-assets/*` into `./public` - * -> create `testcases.json` into `./public` - */ -const fs = require('fs') -const objectHash = require('object-hash') -const codeBlocks = require('gfm-code-blocks') -const fastmatter = require('fastmatter') -const { - www: { url, baseDir }, -} = require('./../package.json') -const createFile = require('../build/create-file') -const getAllMatchesForRegex = require('./get-all-matches-for-regex') -const queries = require('./queries') -const regexps = require('./reg-exps') -const copyTestcasesAssets = require('./copy-testcases-assets') -const createTestcasesJson = require('./create-testcases-json') -const createTestcasesOfRuleOfEmReportTool = require('./create-testcases-of-rule-of-em-report-tool') - -const createTestcasesOfAllRules = options => { - const { graphql } = options - - return graphql(queries.getAllRules).then(async ({ errors, data }) => { - if (errors) { - Promise.reject(errors) - } - - let allRulesTestcases = [] - - /** - * iterate all rule pages - * -> get code snippets - * -> and their relevant titles - */ - const allRulePages = data.allMarkdownRemark.edges - - allRulePages.forEach(markdownPage => { - const { node } = markdownPage - const { rawMarkdownBody, frontmatter, fields } = node - const { fastmatterAttributes } = fields - const { - accessibility_requirements: ruleAccessibilityRequirements, - } = JSON.parse(fastmatterAttributes) - const { name: ruleName } = frontmatter - const { slug } = fields - const ruleId = slug.replace('rules/', '') - const codeTitles = getAllMatchesForRegex( - regexps.testcaseTitle, - rawMarkdownBody - ) - const codeSnippets = codeBlocks(rawMarkdownBody) - - if (codeTitles.length !== codeSnippets.length) { - throw new Error( - `Number of matching titles for code snippets is wrong. Check markdown '${ruleName}' for irregularities. Slug: '${slug}'` - ) - } - - /** - * iterate each code snippet - * -> create a testcase file - * -> and add meta of testcase to `testcases.json` - */ - const ruleTestcases = codeSnippets.reduce((out, codeBlock, index) => { - const title = codeTitles[index] - if (!title) { - throw new Error('No title found for code snippet.') - } - - const { code, block } = codeBlock - let { type = 'html' } = codeBlock - - if (regexps.testcaseCodeSnippetTypeIsSvg.test(block.substring(0, 15))) { - type = 'svg' - } - - const codeId = objectHash({ - block, - type, - ruleId, - }) - - const titleCurated = title.value.split(' ').map(t => t.toLowerCase()) - - const testcaseFileName = `${ruleId}/${codeId}.${type}` - const testcasePath = `testcases/${testcaseFileName}` - /** - * Create testcase file - */ - createFile(`${baseDir}/${testcasePath}`, code) - - /** - * Create meta data for testcase(s) - */ - const testcase = { - testcaseId: codeId, - url: `${url}/${testcasePath}`, - expected: titleCurated[0], - ruleId, - ruleName, - rulePage: `${url}/${slug}`, - ruleAccessibilityRequirements, - } - - out.push(testcase) - return out - }, []) - - // add rule testcases to all testcases - allRulesTestcases = allRulesTestcases.concat(ruleTestcases) - - /** - * Create test cases of rule for use with `em report tool` - */ - createTestcasesOfRuleOfEmReportTool({ - ruleId, - ruleName, - ruleTestcases, - ruleAccessibilityRequirements, - }) - }) - - /** - * Copy `test-assets` that are used by `testcases` - */ - await copyTestcasesAssets() - - /** - * Generate `testcases.json` - */ - await createTestcasesJson(allRulesTestcases) - - console.info(`\nDONE!!! Generated Test Cases.\n`) - }) -} - -module.exports = createTestcasesOfAllRules diff --git a/package.json b/package.json index 4c2372fd1c..0a790fc98a 100644 --- a/package.json +++ b/package.json @@ -152,8 +152,9 @@ "get:implementations": "npm run get:implementation:accessEngine && npm run get:implementation:alfa && npm run get:implementation:axe && npm run get:implementation:rgaa", "create:implementations:metrics": "node ./build/create-implementation-metrics", "implementations": "npm run get:implementations && npm run create:implementations:metrics", + "testcases": "node ./build/create-testcases", "get:wcag:data": "node ./build/get-wcag-data", - "get:data": "npm run get:wcag:data && npm run implementations" + "get:data": "npm run get:wcag:data && npm run implementations && npm run testcases" }, "homepage": "https://github.com/act-rules/act-rules.github.io", "repository": { diff --git a/src/templates/coverage.js b/src/templates/coverage.js index 448bce6c95..d7192f7adc 100644 --- a/src/templates/coverage.js +++ b/src/templates/coverage.js @@ -2,16 +2,14 @@ import React from 'react' import Layout from '../components/layout' import { graphql } from 'gatsby' import SEO from '../components/seo' -import pkg from './../../package.json' export default ({ data }) => { const { markdownRemark, site } = data const { html, frontmatter } = markdownRemark const updatedTitle = `${frontmatter.title} | ${site.siteMetadata.title}` - const { - config: { implementations }, - } = pkg + + const implementations = [] // todo return ( diff --git a/src/templates/rule.js b/src/templates/rule.js index 794bed3251..1ffccf754c 100644 --- a/src/templates/rule.js +++ b/src/templates/rule.js @@ -83,6 +83,7 @@ export default ({ data }) => { repository.url, `_rules/${relativePath}` )} +
    {/* implementations */} {getImplementations(slug)} {/* acknowledgements */} diff --git a/test/utils/get-rules-data.js b/test/utils/get-rules-data.js index 840be09a54..5f22337cbf 100644 --- a/test/utils/get-rules-data.js +++ b/test/utils/get-rules-data.js @@ -1,23 +1,12 @@ -const fs = require('fs') -const path = require('path') const globby = require('globby') -const fastmatter = require('fastmatter') +const getMarkdownData = require('./../../utils/get-markdown-data') /** * Read all `markdown` files content from `_rules/*.md` */ const getRulesData = () => { return globby.sync([`./_rules/*.md`]) - .map(rulePath => { - const filename = path.parse(rulePath).base - const fileContents = fs.readFileSync(rulePath, { encoding: 'utf-8' }) - const { attributes: frontmatter, body } = fastmatter(fileContents) - return { - filename, - frontmatter, - body - } - }) + .map(rulePath => getMarkdownData(rulePath)) } module.exports = getRulesData \ No newline at end of file diff --git a/build/create-file.js b/utils/create-file.js similarity index 100% rename from build/create-file.js rename to utils/create-file.js diff --git a/gatsby/get-all-matches-for-regex.js b/utils/get-all-matches-for-regex.js similarity index 71% rename from gatsby/get-all-matches-for-regex.js rename to utils/get-all-matches-for-regex.js index f2ac6d9e52..7089f52b37 100644 --- a/gatsby/get-all-matches-for-regex.js +++ b/utils/get-all-matches-for-regex.js @@ -1,3 +1,10 @@ +/** + * Given a string, get all values that match specified regular expression + * + * @param {String} regex regular expression + * @param {*} compareString string against which reg exp has to be evaluated + * @param {*} computeIndexes boolean representing if line and column number should be computed + */ const getAllMatchesForRegex = (regex, compareString, computeIndexes = true) => { if (typeof compareString !== 'string') { throw new TypeError('Expected a string to match.') diff --git a/utils/get-markdown-data.js b/utils/get-markdown-data.js new file mode 100644 index 0000000000..bf09d73f01 --- /dev/null +++ b/utils/get-markdown-data.js @@ -0,0 +1,16 @@ +const path = require('path') +const fastmatter = require('fastmatter') +const readFile = require('./read-file') + +const getMarkdownData = (markdownPath) => { + const filename = path.parse(markdownPath).base + const fileContents = readFile(markdownPath) + const { attributes: frontmatter, body } = fastmatter(fileContents) + return { + filename, + frontmatter, + body + } +} + +module.exports = getMarkdownData \ No newline at end of file diff --git a/build/read-file.js b/utils/read-file.js similarity index 100% rename from build/read-file.js rename to utils/read-file.js diff --git a/gatsby/reg-exps.js b/utils/reg-exps.js similarity index 100% rename from gatsby/reg-exps.js rename to utils/reg-exps.js From f06c716884618eba2a9ef48bedb90a6e66244e97 Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 17 Jun 2019 14:49:01 +0100 Subject: [PATCH 09/20] generate html reports from implementation metrics --- build/create-implementation-metrics.js | 20 ++++- .../get-implementation-for-report.js | 1 + .../get-testcase-relative-url.js | 8 +- .../get-testcases-grouped-by-rule.js | 11 +-- gatsby/create-page-add-md-context.js | 6 +- gatsby/create-page-implementer-report.js | 34 +++++++ gatsby/create-pages.js | 6 ++ gatsby/get-component.js | 18 ---- gatsby/get-node-data.js | 2 +- gatsby/get-template.js | 21 +++++ package.json | 4 +- src/components/layout/index.scss | 6 ++ src/styles/base.scss | 2 +- .../{coverage.js => implementations.js} | 26 +++--- src/templates/implementer.js | 88 +++++++++++++++++++ src/utils/render-fragments.js | 14 +-- {gatsby => utils}/get-git-log.js | 0 17 files changed, 206 insertions(+), 61 deletions(-) create mode 100644 gatsby/create-page-implementer-report.js delete mode 100644 gatsby/get-component.js create mode 100644 gatsby/get-template.js rename src/templates/{coverage.js => implementations.js} (74%) create mode 100644 src/templates/implementer.js rename {gatsby => utils}/get-git-log.js (100%) diff --git a/build/create-implementation-metrics.js b/build/create-implementation-metrics.js index fe1976c61e..ea01a99111 100644 --- a/build/create-implementation-metrics.js +++ b/build/create-implementation-metrics.js @@ -15,14 +15,20 @@ const init = async () => { return JSON.parse(fileContent) }) - /** - * transform data, to be grouped by rule id. - */ + const implementers = [] const implementationsGroupedByRuleId = {} reports.forEach(report => { const { tool, organisation, data } = report + /** + * Create data that can be used in `src/templates/coverage.js` + */ + implementers.push(report) + + /** + * Iterate each implementation & group by rule id + */ data.forEach(({ ruleId, implementation }) => { if (!implementation) { return @@ -49,6 +55,14 @@ const init = async () => { }) }) + /** + * Create `implementations.json` + */ + await createFile( + `_data/implementers.json`, + JSON.stringify(implementers, null, 2) + ) + /** * Create metrics in `_data` for usage in `site` */ diff --git a/build/implementations/get-implementation-for-report.js b/build/implementations/get-implementation-for-report.js index df1371ca49..dfdbd25515 100644 --- a/build/implementations/get-implementation-for-report.js +++ b/build/implementations/get-implementation-for-report.js @@ -17,6 +17,7 @@ const getImplementationForReport = async reports => { const implementation = getRuleMapping(ruleTestcases, assertions) return { ruleId, + ruleName: ruleTestcases[0].ruleName, implementation, } }) diff --git a/build/implementations/get-testcase-relative-url.js b/build/implementations/get-testcase-relative-url.js index 1b57dc0763..83b09b0cce 100644 --- a/build/implementations/get-testcase-relative-url.js +++ b/build/implementations/get-testcase-relative-url.js @@ -1,15 +1,11 @@ -const { - www: { url: siteUrl }, -} = require('./../../package.json') - /** * Get relative (suffix) from url * * @param {String} url url */ const getTestcaseRelativeUrl = url => { - const urlPrefix = `${siteUrl}/testcases/` - return url.substr(url.indexOf(urlPrefix)) + const index = url.indexOf(`/testcases/`) + return url.substring(index) } module.exports = getTestcaseRelativeUrl diff --git a/build/implementations/get-testcases-grouped-by-rule.js b/build/implementations/get-testcases-grouped-by-rule.js index 78bfe3d16b..3690ebff85 100644 --- a/build/implementations/get-testcases-grouped-by-rule.js +++ b/build/implementations/get-testcases-grouped-by-rule.js @@ -1,15 +1,12 @@ -const axios = require('axios') -const { config } = require('./../../package.json') +const testcasesData = require('./../../public/testcases.json') /** * Get testcases of rules * - group them by `ruleId` */ -const getTestcasesGroupedByRule = async () => { - const testcasesUrl = config['testcases-url'] - const { data } = await axios.get(testcasesUrl) - const { testcases } = data - +const getTestcasesGroupedByRule = () => { + const { testcases } = testcasesData + return testcases.reduce((out, testcase) => { const { ruleId } = testcase if (!out[ruleId]) { diff --git a/gatsby/create-page-add-md-context.js b/gatsby/create-page-add-md-context.js index b955f1e281..e31d85e436 100644 --- a/gatsby/create-page-add-md-context.js +++ b/gatsby/create-page-add-md-context.js @@ -3,8 +3,8 @@ * -> get all data necessary from `on-create-node` callback * -> extend `context` object on `markdown` pages */ -const path = require('path') -const getComponent = require('./get-component') + +const getTemplate = require('./get-template') const createPageAddMdContext = options => { const { graphql, actions } = options @@ -57,7 +57,7 @@ const createPageAddMdContext = options => { createPage({ path: slug, - component: path.resolve(getComponent(markdownType, slug)), + component: getTemplate(markdownType, slug), context: { slug, fileName, diff --git a/gatsby/create-page-implementer-report.js b/gatsby/create-page-implementer-report.js new file mode 100644 index 0000000000..43a6845df8 --- /dev/null +++ b/gatsby/create-page-implementer-report.js @@ -0,0 +1,34 @@ +const implementers = require('../_data/implementers.json'); +const getTemplate = require('./get-template') + +const createPageImplementerReport = (options) => { + const { actions } = options + const { createPage } = actions + + // Your component that should be rendered for every item in JSON. + + // Create pages for each JSON entry. + implementers.forEach(implementer => { + const { tool, organisation } = implementer + + const filename = tool + .split(' ') + .join('-') + .toLowerCase() + + const slug = `implementation/${filename}`; + + createPage({ + path: slug, + component: getTemplate('implementer'), + context: { + slug, + filename, + title: `Implementation Report of ${tool} (${organisation})`, + data: JSON.stringify(implementer) + } + }); + }); +} + +module.exports = createPageImplementerReport \ No newline at end of file diff --git a/gatsby/create-pages.js b/gatsby/create-pages.js index ea9cdab5f1..75548bbe85 100644 --- a/gatsby/create-pages.js +++ b/gatsby/create-pages.js @@ -1,5 +1,6 @@ const createPageAddMdContext = require('./create-page-add-md-context') const createGlossaryUsagesInRules = require('./create-glossary-uages-in-rules') +const createPageImplementerReport = require('./create-page-implementer-report') const createPages = async options => { const promises = [ @@ -16,6 +17,11 @@ const createPages = async options => { * -> this is saved in `_data` which is later used in `pages/glossary` */ createGlossaryUsagesInRules(options), + + /** + * Create implementation report pages + */ + createPageImplementerReport(options) ] await Promise.all(promises) diff --git a/gatsby/get-component.js b/gatsby/get-component.js deleted file mode 100644 index 744ab85c50..0000000000 --- a/gatsby/get-component.js +++ /dev/null @@ -1,18 +0,0 @@ -function getComponent(type, slug) { - const map = { - glossary: './src/templates/glossary.js', - rules: './src/templates/rule.js', - } - - if (Object.keys(map).includes(type)) { - return map[type] - } - - if (type === 'implementations' && slug.includes('overview')) { - return './src/templates/coverage.js' - } - - return './src/templates/default.js' -} - -module.exports = getComponent diff --git a/gatsby/get-node-data.js b/gatsby/get-node-data.js index 47e15bcafb..dec706d0b2 100644 --- a/gatsby/get-node-data.js +++ b/gatsby/get-node-data.js @@ -1,7 +1,7 @@ const fs = require('fs') const fastmatter = require('fastmatter') const { createFilePath } = require('gatsby-source-filesystem') -const getGitLog = require('./get-git-log') +const getGitLog = require('./../utils/get-git-log') /** * Get node data, to enhance metadata of pages diff --git a/gatsby/get-template.js b/gatsby/get-template.js new file mode 100644 index 0000000000..c567fac561 --- /dev/null +++ b/gatsby/get-template.js @@ -0,0 +1,21 @@ +const path = require('path') + +const getTemplate = (type, slug) => { + const map = { + glossary: './src/templates/glossary.js', + rules: './src/templates/rule.js', + implementer: './src/templates/implementer.js' + } + + if (Object.keys(map).includes(type)) { + return path.resolve(map[type]) + } + + if (type === 'implementations' && slug.includes('overview')) { + return path.resolve('./src/templates/implementations.js') + } + + return path.resolve('./src/templates/default.js') +} + +module.exports = getTemplate diff --git a/package.json b/package.json index 0a790fc98a..bc3df5b245 100644 --- a/package.json +++ b/package.json @@ -152,9 +152,9 @@ "get:implementations": "npm run get:implementation:accessEngine && npm run get:implementation:alfa && npm run get:implementation:axe && npm run get:implementation:rgaa", "create:implementations:metrics": "node ./build/create-implementation-metrics", "implementations": "npm run get:implementations && npm run create:implementations:metrics", - "testcases": "node ./build/create-testcases", + "create:testcases": "node ./build/create-testcases", "get:wcag:data": "node ./build/get-wcag-data", - "get:data": "npm run get:wcag:data && npm run implementations && npm run testcases" + "get:data": "npm run get:wcag:data && npm run create:testcases && npm run implementations" }, "homepage": "https://github.com/act-rules/act-rules.github.io", "repository": { diff --git a/src/components/layout/index.scss b/src/components/layout/index.scss index 7f6311d390..8f05043913 100644 --- a/src/components/layout/index.scss +++ b/src/components/layout/index.scss @@ -124,6 +124,12 @@ section.layout-container { margin-top: 3rem; } + &.page-implementers { + h1, h2, h3, h4, h5, h6 { + display: inline-block; + } + } + // Styles for rules page &.page-rules{ .rules-listing { diff --git a/src/styles/base.scss b/src/styles/base.scss index 43fe0151a2..9790f2b9b8 100644 --- a/src/styles/base.scss +++ b/src/styles/base.scss @@ -6,7 +6,7 @@ body { } h1, h2, h3, h4, h5, h6 { - @include header-style($fg-primary) + @include header-style($fg-primary); } ul{ diff --git a/src/templates/coverage.js b/src/templates/implementations.js similarity index 74% rename from src/templates/coverage.js rename to src/templates/implementations.js index d7192f7adc..d77a3f57b6 100644 --- a/src/templates/coverage.js +++ b/src/templates/implementations.js @@ -2,6 +2,7 @@ import React from 'react' import Layout from '../components/layout' import { graphql } from 'gatsby' import SEO from '../components/seo' +import implementers from './../../_data/implementers' export default ({ data }) => { const { markdownRemark, site } = data @@ -9,8 +10,6 @@ export default ({ data }) => { const updatedTitle = `${frontmatter.title} | ${site.siteMetadata.title}` - const implementations = [] // todo - return ( @@ -22,30 +21,27 @@ export default ({ data }) => { - - {/* */} - {implementations.map((row, index) => { - const { provider, tool } = row - const reportUrl = `` // todo + {implementers.map(row => { + const { organisation, tool } = row + const filename = tool + .split(' ') + .join('-') + .toLowerCase() + const reportUrl = `/implementation/${filename}` return ( - - + {/* TODO: */} {/* */} - + diff --git a/src/templates/implementer.js b/src/templates/implementer.js new file mode 100644 index 0000000000..8035e1caa8 --- /dev/null +++ b/src/templates/implementer.js @@ -0,0 +1,88 @@ +import React from 'react' +import Layout from '../components/layout' +import { graphql } from 'gatsby' +import SEO from '../components/seo' + +export default ({ data }) => { + const { site, sitePage } = data + const { context } = sitePage + const { title: pageTitle, data: contextData } = context + + const updatedTitle = `${pageTitle} | ${site.siteMetadata.title}` + const report = JSON.parse(contextData) + const { data: ruleImplementations } = report + + return ( + + +
    +

    {pageTitle}

    + { + ruleImplementations.map((ruleImplementation, index) => { + const { ruleId, ruleName, implementation } = ruleImplementation + const { assertions } = implementation[0]; + const key = `${index}-${ruleId}` + return ( +
    # Tool NameVersionCreated By Report
    {index + 1}
    {tool}{row.vendorToolVersion}{provider}{organisation} - + View Report
    + + + + + + + + + {assertions.map((assertion, index) => { + const { url, expected, actual } = assertion + const key = `${index}-${url}` + return ( + + + + + + ) + })} + +
    Testcase UrlExpectedActual
    + + {url} + + {expected}{actual}
    + } + + ) + }) + } + +
    + ) +} + +export const query = graphql` + query($path: String!) { + sitePage(path: {eq: $path }) { + context { + data + title + } + } + site { + siteMetadata { + title + keywords + } + } + } +` diff --git a/src/utils/render-fragments.js b/src/utils/render-fragments.js index 4140b7afd0..92b4fbf5a8 100644 --- a/src/utils/render-fragments.js +++ b/src/utils/render-fragments.js @@ -25,14 +25,18 @@ export const getImplementations = slug => {
    {tool}{provider}{organisation} - + View Report {row.vendorToolVersion}{organisation} - - View Report - + View Report
    - - - - - - - - - {assertions.map((assertion, index) => { - const { url, expected, actual } = assertion - const key = `${index}-${url}` - return ( - - - - - - ) - })} - -
    Testcase UrlExpectedActual
    - - {url} - - {expected}{actual}
    - } -
    - ) - }) - } - -
    - ) + return ( + + +
    +

    {pageTitle}

    + {ruleImplementations.map((ruleImplementation, index) => { + const { ruleId, ruleName, implementation } = ruleImplementation + const { assertions } = implementation[0] + const key = `${index}-${ruleId}` + return ( +
    + {/* */} +

    {ruleName}

    + {/*
    */} +    + View Rule + { + + + + + + + + + + {assertions.map((assertion, index) => { + const { url, expected, actual } = assertion + const key = `${index}-${url}` + return ( + + + + + + ) + })} + +
    Testcase UrlExpectedActual
    + + {url} + + {expected}{actual}
    + } +
    + ) + })} +
    +
    + ) } export const query = graphql` - query($path: String!) { - sitePage(path: {eq: $path }) { - context { - data - title - } - } + query($path: String!) { + sitePage(path: { eq: $path }) { + context { + data + title + } + } site { siteMetadata { title diff --git a/src/utils/render-fragments.js b/src/utils/render-fragments.js index 92b4fbf5a8..66cda8466d 100644 --- a/src/utils/render-fragments.js +++ b/src/utils/render-fragments.js @@ -36,9 +36,7 @@ export const getImplementations = slug => { {tool} {organisation} - - View Report - + View Report ) From 5d0b583433fbbb5266ba9ac8f9519666819097a0 Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 17 Jun 2019 15:35:34 +0100 Subject: [PATCH 12/20] update package.json --- package.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/package.json b/package.json index 2a48b4c489..d11028acb0 100644 --- a/package.json +++ b/package.json @@ -148,7 +148,7 @@ "get:implementation:accessEngine": "node ./build/get-implementation --org \"Level Access\" --tool \"Access Engine\" --path \"./node_modules/act-rules-implementation-access-engine/report.json\"", "get:implementation:alfa": "node ./build/get-implementation --org \"Site Improve\" --tool \"Alfa\" --path \"https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json\"", "get:implementation:axe": "node ./build/get-implementation --org \"Deque Systems\" --tool \"Axe\" --path \"./node_modules/act-rules-implementation-axe-core/report.json\"", - "get:implementation:rgaa": "node ./build/get-implementation --org \"Access42\" --tool \"RGAA 3.0\" --path $npm_package_config_implementations_rgaa", + "get:implementation:rgaa": "node ./build/get-implementation --org \"Access42\" --tool \"RGAA 3.0\" --path \"./node_modules/act-rules-implementation-rgaa/reports/*.json\"", "get:implementations": "npm run get:implementation:accessEngine && npm run get:implementation:alfa && npm run get:implementation:axe && npm run get:implementation:rgaa", "create:implementations:metrics": "node ./build/create-implementation-metrics", "implementations": "npm run get:implementations && npm run create:implementations:metrics", @@ -176,11 +176,6 @@ "references": { "wcag21": "https://raw.githubusercontent.com/w3c/wai-wcag-quickref/gh-pages/_data/wcag21.json" }, - "testcases-url": "https://act-rules.github.io/testcases.json", - "implementations": { - "axe": "./node_modules/act-rules-implementation-axe-core/report.json", - "rgaa": "./node_modules/act-rules-implementation-rgaa/reports/*.json" - }, "rule-format-metadata": { "input-aspects": { "default": "https://www.w3.org/TR/act-rules-aspects/#intro", From 655fa19720907ba64a434daa3fb85f253325b38c Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 24 Jun 2019 09:49:45 +0100 Subject: [PATCH 13/20] refactor before adding tests --- package.json | 2 +- .../{rule-filename.test.js => rule/filename.test.js} | 2 +- .../frontmatter.test.js} | 4 ++-- .../{rule-headings.test.js => rule/headings.test.js} | 8 +++----- test/{utils => test-utils}/describe-rule.js | 9 +++++++-- .../get-all-headings-from-markdown-body.js | 0 test/{utils => test-utils}/get-heading-of-depth.js | 0 test/utils/get-rules-data.js | 12 ------------ 8 files changed, 14 insertions(+), 23 deletions(-) rename test/{rule-filename.test.js => rule/filename.test.js} (84%) rename test/{rule-frontmatter.test.js => rule/frontmatter.test.js} (92%) rename test/{rule-headings.test.js => rule/headings.test.js} (73%) rename test/{utils => test-utils}/describe-rule.js (68%) rename test/{utils => test-utils}/get-all-headings-from-markdown-body.js (100%) rename test/{utils => test-utils}/get-heading-of-depth.js (100%) delete mode 100644 test/utils/get-rules-data.js diff --git a/package.json b/package.json index d11028acb0..2cdd512247 100644 --- a/package.json +++ b/package.json @@ -191,7 +191,7 @@ "verbose": true, "bail": true, "testPathIgnorePatterns": [ - "/test/utils/", + "/test/test-utils/", "/.cache/", "/.public/" ] diff --git a/test/rule-filename.test.js b/test/rule/filename.test.js similarity index 84% rename from test/rule-filename.test.js rename to test/rule/filename.test.js index 5913e552d3..a84499d533 100644 --- a/test/rule-filename.test.js +++ b/test/rule/filename.test.js @@ -1,4 +1,4 @@ -const describeRule = require('./utils/describe-rule') +const describeRule = require('../test-utils/describe-rule') describeRule('filename', ruleData => { const { filename, frontmatter } = ruleData diff --git a/test/rule-frontmatter.test.js b/test/rule/frontmatter.test.js similarity index 92% rename from test/rule-frontmatter.test.js rename to test/rule/frontmatter.test.js index 3af248b4e5..b7469f1387 100644 --- a/test/rule-frontmatter.test.js +++ b/test/rule/frontmatter.test.js @@ -1,6 +1,6 @@ -const describeRule = require('./utils/describe-rule') -const { contributors } = require('./../package.json') +const describeRule = require('../test-utils/describe-rule') +const { contributors } = require('./../../package.json') const contributorsNames = contributors.map(contributor => contributor.name.toLowerCase()) describeRule('frontmatter', (ruleData) => { diff --git a/test/rule-headings.test.js b/test/rule/headings.test.js similarity index 73% rename from test/rule-headings.test.js rename to test/rule/headings.test.js index a434177b1e..e1c2501799 100644 --- a/test/rule-headings.test.js +++ b/test/rule/headings.test.js @@ -1,13 +1,11 @@ -const describeRule = require('./utils/describe-rule') -const getAllHeadingsFromMarkdownBody = require('./utils/get-all-headings-from-markdown-body') -const getHeadingOfDepth = require('./utils/get-heading-of-depth') +const describeRule = require('../test-utils/describe-rule') +const getAllHeadingsFromMarkdownBody = require('../test-utils/get-all-headings-from-markdown-body') +const getHeadingOfDepth = require('../test-utils/get-heading-of-depth') describeRule('headings', (ruleData) => { const { body } = ruleData const headings = getAllHeadingsFromMarkdownBody(body) - const level3Headings = getHeadingOfDepth(headings, 3) - /** * Check for `required` `h2` headings */ diff --git a/test/utils/describe-rule.js b/test/test-utils/describe-rule.js similarity index 68% rename from test/utils/describe-rule.js rename to test/test-utils/describe-rule.js index 1e241d20a7..8d6a2cc16c 100644 --- a/test/utils/describe-rule.js +++ b/test/test-utils/describe-rule.js @@ -1,5 +1,5 @@ -const getRulesData = require('./get-rules-data') -const rules = getRulesData() +const globby = require('globby') +const getMarkdownData = require('../../utils/get-markdown-data') /** * @@ -7,6 +7,11 @@ const rules = getRulesData() * @param {Function} runTests function callback of `describe` block, which executes per rule */ const describeRule = (groupName, runTests) => { + + const rules = globby.sync([`./_rules/*.md`]).map( + rulePath => getMarkdownData(rulePath) + ) + rules.forEach(ruleData => { const { filename } = ruleData describe(filename, () => { diff --git a/test/utils/get-all-headings-from-markdown-body.js b/test/test-utils/get-all-headings-from-markdown-body.js similarity index 100% rename from test/utils/get-all-headings-from-markdown-body.js rename to test/test-utils/get-all-headings-from-markdown-body.js diff --git a/test/utils/get-heading-of-depth.js b/test/test-utils/get-heading-of-depth.js similarity index 100% rename from test/utils/get-heading-of-depth.js rename to test/test-utils/get-heading-of-depth.js diff --git a/test/utils/get-rules-data.js b/test/utils/get-rules-data.js deleted file mode 100644 index 5f22337cbf..0000000000 --- a/test/utils/get-rules-data.js +++ /dev/null @@ -1,12 +0,0 @@ -const globby = require('globby') -const getMarkdownData = require('./../../utils/get-markdown-data') - -/** - * Read all `markdown` files content from `_rules/*.md` - */ -const getRulesData = () => { - return globby.sync([`./_rules/*.md`]) - .map(rulePath => getMarkdownData(rulePath)) -} - -module.exports = getRulesData \ No newline at end of file From dc173f4e5eba645546fee1788d71c3053db920c5 Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 24 Jun 2019 13:37:14 +0100 Subject: [PATCH 14/20] add jsdocs --- build/create-glossary-usages.js | 5 +++- build/create-testcases.js | 2 +- build/get-wcag-data.js | 50 ++++++++++++++++++++++----------- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/build/create-glossary-usages.js b/build/create-glossary-usages.js index da851a13c5..15cc9371d9 100644 --- a/build/create-glossary-usages.js +++ b/build/create-glossary-usages.js @@ -81,6 +81,9 @@ const init = async () => { ) } +/** + * Invoke + */ init() - .then(() => console.info(`\nGenerated Glossary Usages Data.\n`)) + .then(() => console.info(`Completed: task: create:glossary\n`)) .catch(e => console.error(e)) diff --git a/build/create-testcases.js b/build/create-testcases.js index 5bb1fd4ede..5cb52f659a 100644 --- a/build/create-testcases.js +++ b/build/create-testcases.js @@ -141,7 +141,7 @@ const init = async () => { * Invoke */ init() - .then(`Created testcases`) + .then(() => console.log('Completed: task: create:testcases')) .catch(e => { console.error(e) process.write(1) diff --git a/build/get-wcag-data.js b/build/get-wcag-data.js index 8e61fc89bb..51f6c95b10 100644 --- a/build/get-wcag-data.js +++ b/build/get-wcag-data.js @@ -15,6 +15,10 @@ const outputFileScEmReportAuditResult = path.join( 'sc-em-report-audit-result.json' ) +/** + * Determine if a given success criteria is 2.0 + * @param {Object} sc success criterion + */ const isScWcag20 = sc => { const is20 = !( sc.versions && @@ -24,6 +28,10 @@ const isScWcag20 = sc => { return is20 } +/** + * Get enhanced meta data of success criterion + * @param {Object} sc success criteria + */ const getMetaData = sc => { const urlPrefix = `https://www.w3.org/TR/WCAG` const is20 = isScWcag20(sc) @@ -34,12 +42,12 @@ const getMetaData = sc => { is20 ? 'http://www.w3.org/WAI/WCAG20/quickref/#qr-' : 'https://www.w3.org/WAI/WCAG21/quickref/#' - }${path}` + }${path}` const understandingUrl = `${ is20 ? 'http://www.w3.org/TR/UNDERSTANDING-WCAG20/' : 'https://www.w3.org/WAI/WCAG21/Understanding/' - }/${path}.html` + }/${path}.html` /** * Construct `test` - used by `wcag em report tool` */ @@ -59,10 +67,14 @@ const getMetaData = sc => { } } -const getScMetaData = async url => { - const { data } = await axios.get(url) +/** + * Get all WCAG SC reference data + * @param {String} url URL + */ +const getWaiWcagReferenceData = async url => { + const { data: { principles } } = await axios.get(url) + const scMetaData = {} - const { principles } = data principles.forEach(p => p.guidelines.forEach(g => g.successcriteria.forEach(sc => { @@ -73,8 +85,12 @@ const getScMetaData = async url => { return scMetaData } -;(async () => { +/** + * Init + */ +const init = async () => { const wcagReferenceUrl = pkg.config.references.wcag21 + if (!wcagReferenceUrl) { throw new Error('No reference URL for WCAG21 is specified in config.') } @@ -82,11 +98,8 @@ const getScMetaData = async url => { /** * Create a list of success criteria meta data */ - const scMetaData = await getScMetaData(wcagReferenceUrl) - await createFile( - outputFileScMetaData, - JSON.stringify(scMetaData, undefined, 2) - ) + const scMetaData = await getWaiWcagReferenceData(wcagReferenceUrl) + await createFile(outputFileScMetaData, JSON.stringify(scMetaData, undefined, 2)) /** * Create wcag em report tool friendly audit result array @@ -106,10 +119,13 @@ const getScMetaData = async url => { hasPart: [], } }) - await createFile( - outputFileScEmReportAuditResult, - JSON.stringify(scEmReportAuditResult, undefined, 2) - ) - console.info('\nGenerated WCAG Success Criterion Data.\n') -})() + await createFile(outputFileScEmReportAuditResult, JSON.stringify(scEmReportAuditResult, undefined, 2)) +} + +/** + * Invoke + */ +init() + .then(() => console.info('Completed: task: get:wcag:data.\n')) + .catch(e => console.error(e)) From 2c9b1541870678ed7cf1459f2c9b2ebd6fac8973 Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 24 Jun 2019 13:58:11 +0100 Subject: [PATCH 15/20] fix: for not gernerating multiple rule reports --- build/implementations/get-best-matching-rules.js | 2 +- build/implementations/get-framed-report.js | 4 ++-- package.json | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build/implementations/get-best-matching-rules.js b/build/implementations/get-best-matching-rules.js index a9422971b6..5e2e14299b 100644 --- a/build/implementations/get-best-matching-rules.js +++ b/build/implementations/get-best-matching-rules.js @@ -10,7 +10,7 @@ const getBestMatchingRules = ruleAsserts => { } const completeRules = mappedRules.filter(({ complete }) => complete === true) - if (!completeRules) { + if (!completeRules.length) { return mappedRules } diff --git a/build/implementations/get-framed-report.js b/build/implementations/get-framed-report.js index af1acdaa72..aab4e1be7a 100644 --- a/build/implementations/get-framed-report.js +++ b/build/implementations/get-framed-report.js @@ -11,13 +11,13 @@ const getFramedReport = async path => { return await jsonld.frame(data, frameConfig) } - const reports = globby.sync([path]).map(reportPath => { + const reportFiles = globby.sync([path]); + const reports = reportFiles.map(reportPath => { const fileContent = readFile(reportPath) return JSON.parse(fileContent) }) const result = [] - for (let report of reports) { const framedReport = await jsonld.frame(report, frameConfig) result.push(framedReport) diff --git a/package.json b/package.json index 2cdd512247..5f788bc900 100644 --- a/package.json +++ b/package.json @@ -145,10 +145,10 @@ "serve": "gatsby serve", "test": "npm run test:rules", "test:rules": "jest", - "get:implementation:accessEngine": "node ./build/get-implementation --org \"Level Access\" --tool \"Access Engine\" --path \"./node_modules/act-rules-implementation-access-engine/report.json\"", - "get:implementation:alfa": "node ./build/get-implementation --org \"Site Improve\" --tool \"Alfa\" --path \"https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json\"", - "get:implementation:axe": "node ./build/get-implementation --org \"Deque Systems\" --tool \"Axe\" --path \"./node_modules/act-rules-implementation-axe-core/report.json\"", - "get:implementation:rgaa": "node ./build/get-implementation --org \"Access42\" --tool \"RGAA 3.0\" --path \"./node_modules/act-rules-implementation-rgaa/reports/*.json\"", + "get:implementation:accessEngine": "node ./build/get-implementation --org 'Level Access' --tool 'Access Engine' --path './node_modules/act-rules-implementation-access-engine/report.json'", + "get:implementation:alfa": "node ./build/get-implementation --org 'Site Improve' --tool 'Alfa' --path 'https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json'", + "get:implementation:axe": "node ./build/get-implementation --org 'Deque Systems' --tool 'Axe' --path './node_modules/act-rules-implementation-axe-core/report.json'", + "get:implementation:rgaa": "node ./build/get-implementation --org 'Access42' --tool 'RGAA 3.0' --path './node_modules/act-rules-implementation-rgaa/reports/*.json'", "get:implementations": "npm run get:implementation:accessEngine && npm run get:implementation:alfa && npm run get:implementation:axe && npm run get:implementation:rgaa", "create:implementations:metrics": "node ./build/create-implementation-metrics", "implementations": "npm run get:implementations && npm run create:implementations:metrics", From 91a2bc393e144059a99da18817f644c800f84dfd Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 24 Jun 2019 15:13:55 +0100 Subject: [PATCH 16/20] add tests --- build/implementations/get-assertions.js | 3 ++ build/implementations/get-framed-report.js | 5 +++ package.json | 4 ++- .../implementations/get-assertions.test.js | 16 ++++++++++ .../implementations/get-framed-report.test.js | 31 +++++++++++++++++++ .../get-implementation-for-report.test.js | 17 ++++++++++ .../get-testcases-grouped-by-rule.test.js | 12 +++++++ test/test-utils/describe-rule.js | 9 ++---- test/test-utils/get-rules.js | 14 +++++++++ 9 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 test/build/implementations/get-assertions.test.js create mode 100644 test/build/implementations/get-framed-report.test.js create mode 100644 test/build/implementations/get-implementation-for-report.test.js create mode 100644 test/build/implementations/get-testcases-grouped-by-rule.test.js create mode 100644 test/test-utils/get-rules.js diff --git a/build/implementations/get-assertions.js b/build/implementations/get-assertions.js index 874b217e34..678678f957 100644 --- a/build/implementations/get-assertions.js +++ b/build/implementations/get-assertions.js @@ -4,6 +4,9 @@ * @param {Object|Array} framedReports implementation reports */ const getAssertions = framedReports => { + if(!framedReports) { + throw new Error('argument report is expected') + } const reports = Array.isArray(framedReports) ? framedReports : [framedReports] return reports.reduce((out, report) => { diff --git a/build/implementations/get-framed-report.js b/build/implementations/get-framed-report.js index aab4e1be7a..051b3c1236 100644 --- a/build/implementations/get-framed-report.js +++ b/build/implementations/get-framed-report.js @@ -6,6 +6,11 @@ const frameConfig = require('./json-ld-frame-config') const readFile = require('../../utils/read-file') const getFramedReport = async path => { + + if(!path) { + throw new Error('Path should be provided from which report has to be obtained.'); + } + if (isUrl(path)) { const { data } = await axios.get(path) return await jsonld.frame(data, frameConfig) diff --git a/package.json b/package.json index 5f788bc900..6cda2b4732 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,7 @@ "start": "npm run clean && npm run develop", "serve": "gatsby serve", "test": "npm run test:rules", - "test:rules": "jest", + "test:rules": "jest --coverage", "get:implementation:accessEngine": "node ./build/get-implementation --org 'Level Access' --tool 'Access Engine' --path './node_modules/act-rules-implementation-access-engine/report.json'", "get:implementation:alfa": "node ./build/get-implementation --org 'Site Improve' --tool 'Alfa' --path 'https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json'", "get:implementation:axe": "node ./build/get-implementation --org 'Deque Systems' --tool 'Axe' --path './node_modules/act-rules-implementation-axe-core/report.json'", @@ -191,6 +191,8 @@ "verbose": true, "bail": true, "testPathIgnorePatterns": [ + "/test/rule/", + "/test/test-utils/", "/.cache/", "/.public/" diff --git a/test/build/implementations/get-assertions.test.js b/test/build/implementations/get-assertions.test.js new file mode 100644 index 0000000000..7c375637d2 --- /dev/null +++ b/test/build/implementations/get-assertions.test.js @@ -0,0 +1,16 @@ +const getFramedReport = require('../../../build/implementations/get-framed-report') +const getAssertions = require('../../../build/implementations/get-assertions') + +describe(`getAssertions`, () => { + it('throws when no argument is specified', () => + expect(() => getAssertions(null)).toThrow() + ) + + it('returns assertions from framed reports', async () => { + const framedReport = await getFramedReport( + `https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json` + ) + const assertions = getAssertions(framedReport) + expect(assertions.length).toBeGreaterThan(0) + }) +}) diff --git a/test/build/implementations/get-framed-report.test.js b/test/build/implementations/get-framed-report.test.js new file mode 100644 index 0000000000..44f2116d12 --- /dev/null +++ b/test/build/implementations/get-framed-report.test.js @@ -0,0 +1,31 @@ +const getFramedReport = require('../../../build/implementations/get-framed-report') + +describe(`getFramedReport`, () => { + it('throws when no argument is specified', async () => + expect(getFramedReport(null)).rejects.toBeInstanceOf(Error) + ) + + it('returns framed report from given URL (1 report)', async () => { + const framedReport = await getFramedReport( + `https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json` + ) + assertFramedReport(framedReport) + }) + + it('returns framed report from files GLOB (multiple reports)', async () => { + const framedReports = await getFramedReport( + `./node_modules/act-rules-implementation-rgaa/reports/*.json` + ) + expect(framedReports.length).toBeGreaterThan(1) + framedReports.forEach((report) => assertFramedReport(report)) + }) +}) + +const assertFramedReport = (report) => { + expect(report).toBeDefined() + const keys = Object.keys(report); + ['@context', '@graph'].forEach((key) => { + expect(keys.includes(key)).toBe(true) + }) + expect(report['@graph'].length).toBeGreaterThan(0) +} \ No newline at end of file diff --git a/test/build/implementations/get-implementation-for-report.test.js b/test/build/implementations/get-implementation-for-report.test.js new file mode 100644 index 0000000000..1bdf806923 --- /dev/null +++ b/test/build/implementations/get-implementation-for-report.test.js @@ -0,0 +1,17 @@ +const getFramedReport = require('../../../build/implementations/get-framed-report') +const getImplementationForReport = require('../../../build/implementations/get-implementation-for-report') + +describe(`getImplementationForReport`, () => { + + it(`gets implementation report`, async () => { + const framedReports = await getFramedReport( + `./node_modules/act-rules-implementation-rgaa/reports/*.json` + ) + const result = await getImplementationForReport(framedReports) + expect(result).toBeDefined() + expect(result.length).toBeGreaterThan(0) + result.forEach((data) => { + expect(Object.keys(data)).toEqual(['ruleId', 'ruleName', 'implementation']) + }) + }) +}) \ No newline at end of file diff --git a/test/build/implementations/get-testcases-grouped-by-rule.test.js b/test/build/implementations/get-testcases-grouped-by-rule.test.js new file mode 100644 index 0000000000..7288446a44 --- /dev/null +++ b/test/build/implementations/get-testcases-grouped-by-rule.test.js @@ -0,0 +1,12 @@ +const getRules = require('./../../test-utils/get-rules') +const getTestcasesGroupedByRule = require('../../../build/implementations/get-testcases-grouped-by-rule') + +describe('getTestcasesGroupedByRule', () => { + + it('should have testcases for every rule', () => { + const rules = getRules() + const groupedTestcases = getTestcasesGroupedByRule() + expect(rules.length).toEqual(Object.keys(groupedTestcases).length) + }) + +}) \ No newline at end of file diff --git a/test/test-utils/describe-rule.js b/test/test-utils/describe-rule.js index 8d6a2cc16c..d213f600f3 100644 --- a/test/test-utils/describe-rule.js +++ b/test/test-utils/describe-rule.js @@ -1,16 +1,13 @@ -const globby = require('globby') -const getMarkdownData = require('../../utils/get-markdown-data') +const getRules = require('./get-rules') /** - * + * describe rule helper * @param {String} groupName name of the `describe` block * @param {Function} runTests function callback of `describe` block, which executes per rule */ const describeRule = (groupName, runTests) => { - const rules = globby.sync([`./_rules/*.md`]).map( - rulePath => getMarkdownData(rulePath) - ) + const rules = getRules() rules.forEach(ruleData => { const { filename } = ruleData diff --git a/test/test-utils/get-rules.js b/test/test-utils/get-rules.js new file mode 100644 index 0000000000..2551e623f4 --- /dev/null +++ b/test/test-utils/get-rules.js @@ -0,0 +1,14 @@ +const globby = require('globby') +const getMarkdownData = require('../../utils/get-markdown-data') + + +/** + * Read all rules & parse the markdown + */ +const getRules = () => { + return globby.sync([`./_rules/*.md`]).map( + rulePath => getMarkdownData(rulePath) + ) +} + +module.exports = getRules \ No newline at end of file From e1a5a263fd7a6f8d625bd62fc7a0b0af6856330e Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 24 Jun 2019 15:23:46 +0100 Subject: [PATCH 17/20] remove testPathIgnore --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index 6cda2b4732..f6ea8c9393 100644 --- a/package.json +++ b/package.json @@ -191,8 +191,6 @@ "verbose": true, "bail": true, "testPathIgnorePatterns": [ - "/test/rule/", - "/test/test-utils/", "/.cache/", "/.public/" From 11a6a1358298c5196d8e655e0468e00098e716b9 Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 24 Jun 2019 15:26:17 +0100 Subject: [PATCH 18/20] add pretest step --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f6ea8c9393..b2e6d23bd5 100644 --- a/package.json +++ b/package.json @@ -143,8 +143,8 @@ "format": "prettier --write *.{json,md,js,jsx} './{_data,_rules,build,gatsby,pages,src,test-assets}/**/*.{json,md,js,jsx}'", "start": "npm run clean && npm run develop", "serve": "gatsby serve", - "test": "npm run test:rules", - "test:rules": "jest --coverage", + "pretest": "npm run get:data", + "test": "jest --coverage", "get:implementation:accessEngine": "node ./build/get-implementation --org 'Level Access' --tool 'Access Engine' --path './node_modules/act-rules-implementation-access-engine/report.json'", "get:implementation:alfa": "node ./build/get-implementation --org 'Site Improve' --tool 'Alfa' --path 'https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json'", "get:implementation:axe": "node ./build/get-implementation --org 'Deque Systems' --tool 'Axe' --path './node_modules/act-rules-implementation-axe-core/report.json'", From ed68a9e0b07eeee4061ca9be7462bdabadd0c1ef Mon Sep 17 00:00:00 2001 From: jkodu Date: Mon, 24 Jun 2019 15:42:26 +0100 Subject: [PATCH 19/20] remove husky hook and add trusted tester report --- package-lock.json | 4 ++++ package.json | 9 +++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 068fe0e4dc..234b6a14a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1653,6 +1653,10 @@ "version": "git+https://git@github.com/act-rules/act-rules-implementation-rgaa.git#1d572a40f6879a75d36090c7275c42e4d0d79cee", "from": "git+https://git@github.com/act-rules/act-rules-implementation-rgaa.git" }, + "act-rules-implementation-trusted-tester": { + "version": "git+https://git@github.com/act-rules/act-rules-implementation-trusted-tester.git#db78eb5206f6bb95fd587628c6c77984576b22e0", + "from": "git+https://git@github.com/act-rules/act-rules-implementation-trusted-tester.git" + }, "address": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/address/-/address-1.0.3.tgz", diff --git a/package.json b/package.json index b2e6d23bd5..c6911120bb 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "act-rules-implementation-access-engine": "git+https://git@github.com/act-rules/act-rules-implementation-access-engine.git", "act-rules-implementation-axe-core": "git+https://git@github.com/act-rules/act-rules-implementation-axe-core.git", "act-rules-implementation-rgaa": "git+https://git@github.com/act-rules/act-rules-implementation-rgaa.git", + "act-rules-implementation-trusted-tester": "git+https://git@github.com/act-rules/act-rules-implementation-trusted-tester.git", "axios": "^0.18.1", "commander": "^2.20.0", "fastmatter": "^2.1.1", @@ -149,7 +150,8 @@ "get:implementation:alfa": "node ./build/get-implementation --org 'Site Improve' --tool 'Alfa' --path 'https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json'", "get:implementation:axe": "node ./build/get-implementation --org 'Deque Systems' --tool 'Axe' --path './node_modules/act-rules-implementation-axe-core/report.json'", "get:implementation:rgaa": "node ./build/get-implementation --org 'Access42' --tool 'RGAA 3.0' --path './node_modules/act-rules-implementation-rgaa/reports/*.json'", - "get:implementations": "npm run get:implementation:accessEngine && npm run get:implementation:alfa && npm run get:implementation:axe && npm run get:implementation:rgaa", + "get:implementation:trustedTester": "node ./build/get-implementation --org 'Trusted Tester' --tool 'Trusted Tester' --path './node_modules/act-rules-implementation-trusted-tester/reports/*.json'", + "get:implementations": "npm run get:implementation:accessEngine && npm run get:implementation:alfa && npm run get:implementation:axe && npm run get:implementation:rgaa && npm run get:implementation:trustedTester", "create:implementations:metrics": "node ./build/create-implementation-metrics", "implementations": "npm run get:implementations && npm run create:implementations:metrics", "create:testcases": "node ./build/create-testcases", @@ -196,11 +198,6 @@ "/.public/" ] }, - "husky": { - "hooks": { - "pre-commit": "npm test" - } - }, "lint-staged": { "*.{md,json,js,html}": [ "prettier --write", From 1721428ad5ed6c5b18043922850c6b53dfbde01d Mon Sep 17 00:00:00 2001 From: jkodu Date: Fri, 28 Jun 2019 16:21:55 +0100 Subject: [PATCH 20/20] update --- build/create-glossary-usages.js | 2 +- build/create-testcases.js | 1 + package-lock.json | 4 ++++ package.json | 35 +++++++++++++++++---------------- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/build/create-glossary-usages.js b/build/create-glossary-usages.js index 15cc9371d9..d47bb31837 100644 --- a/build/create-glossary-usages.js +++ b/build/create-glossary-usages.js @@ -7,7 +7,7 @@ const globby = require('globby') const regexps = require('../utils/reg-exps') const createFile = require('../utils/create-file') const getAllMatchesForRegex = require('../utils/get-all-matches-for-regex') -const getMarkdownData = require('./../utils/get-markdown-data') +const getMarkdownData = require('../utils/get-markdown-data') const init = async () => { /** diff --git a/build/create-testcases.js b/build/create-testcases.js index 5cb52f659a..e060d67003 100644 --- a/build/create-testcases.js +++ b/build/create-testcases.js @@ -99,6 +99,7 @@ const init = async () => { const testcase = { testcaseId: codeId, url: `${url}/${testcasePath}`, + relativePath: testcasePath, expected: titleCurated[0], ruleId, ruleName, diff --git a/package-lock.json b/package-lock.json index 234b6a14a4..22288ae388 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1645,6 +1645,10 @@ "version": "git+https://git@github.com/act-rules/act-rules-implementation-access-engine.git#fc89e8142ff8d2ad37ee411cbf3801b44320df43", "from": "git+https://git@github.com/act-rules/act-rules-implementation-access-engine.git" }, + "act-rules-implementation-alfa": { + "version": "git+https://git@github.com/act-rules/act-rules-implementation-alfa.git#3944f96980ecf3d6d2987b63c00859968119548f", + "from": "git+https://git@github.com/act-rules/act-rules-implementation-alfa.git" + }, "act-rules-implementation-axe-core": { "version": "git+https://git@github.com/act-rules/act-rules-implementation-axe-core.git#3d61261e7998e2b753eac465cd4dfb316269f0ca", "from": "git+https://git@github.com/act-rules/act-rules-implementation-axe-core.git" diff --git a/package.json b/package.json index c6911120bb..eeb4b76e14 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,7 @@ ], "dependencies": { "act-rules-implementation-access-engine": "git+https://git@github.com/act-rules/act-rules-implementation-access-engine.git", + "act-rules-implementation-alfa": "git+https://git@github.com/act-rules/act-rules-implementation-alfa.git", "act-rules-implementation-axe-core": "git+https://git@github.com/act-rules/act-rules-implementation-axe-core.git", "act-rules-implementation-rgaa": "git+https://git@github.com/act-rules/act-rules-implementation-rgaa.git", "act-rules-implementation-trusted-tester": "git+https://git@github.com/act-rules/act-rules-implementation-trusted-tester.git", @@ -137,27 +138,27 @@ "license": "MIT", "scripts": { "clean": "rm -rf .cache public", - "prebuild": "npm run get:data", - "build": "gatsby build", - "predevelop": "npm run get:data", + "getImplementationAccessEngine": "node ./build/get-implementation --org 'Level Access' --tool 'Access Engine' --path './node_modules/act-rules-implementation-access-engine/report.json'", + "getImplementationAlfa": "node ./build/get-implementation --org 'Siteimprove' --tool 'Alfa' --path './node_modules/act-rules-implementation-alfa/report.json'", + "getImplementationAxe": "node ./build/get-implementation --org 'Deque Systems' --tool 'Axe' --path './node_modules/act-rules-implementation-axe-core/report.json'", + "getImplementationRgaa": "node ./build/get-implementation --org 'Access42' --tool 'RGAA 3.0' --path './node_modules/act-rules-implementation-rgaa/reports/*.json'", + "getImplementationTrustedTester": "node ./build/get-implementation --org 'Trusted Tester' --tool 'Trusted Tester' --path './node_modules/act-rules-implementation-trusted-tester/reports/*.json'", + "getImplementations": "npm run getImplementationAccessEngine && npm run getImplementationAlfa && npm run getImplementationAxe && npm run getImplementationRgaa && npm run getImplementationTrustedTester", + "createImplementationsMetrics": "node ./build/create-implementation-metrics", + "implementations": "npm run getImplementations && npm run createImplementationsMetrics", + "createTestcases": "node ./build/create-testcases", + "createGlossary": "node ./build/create-glossary-usages", + "getWcagData": "node ./build/get-wcag-data", + "getData": "npm run getWcagData && npm run createTestcases && npm run createGlossary && npm run implementations", + "predevelop": "npm run getData", "develop": "gatsby develop", + "prebuild": "npm run getData", + "build": "gatsby build", "format": "prettier --write *.{json,md,js,jsx} './{_data,_rules,build,gatsby,pages,src,test-assets}/**/*.{json,md,js,jsx}'", "start": "npm run clean && npm run develop", "serve": "gatsby serve", - "pretest": "npm run get:data", - "test": "jest --coverage", - "get:implementation:accessEngine": "node ./build/get-implementation --org 'Level Access' --tool 'Access Engine' --path './node_modules/act-rules-implementation-access-engine/report.json'", - "get:implementation:alfa": "node ./build/get-implementation --org 'Site Improve' --tool 'Alfa' --path 'https://raw.githubusercontent.com/w3c/earl/master/earl-reports/alfa-report.json'", - "get:implementation:axe": "node ./build/get-implementation --org 'Deque Systems' --tool 'Axe' --path './node_modules/act-rules-implementation-axe-core/report.json'", - "get:implementation:rgaa": "node ./build/get-implementation --org 'Access42' --tool 'RGAA 3.0' --path './node_modules/act-rules-implementation-rgaa/reports/*.json'", - "get:implementation:trustedTester": "node ./build/get-implementation --org 'Trusted Tester' --tool 'Trusted Tester' --path './node_modules/act-rules-implementation-trusted-tester/reports/*.json'", - "get:implementations": "npm run get:implementation:accessEngine && npm run get:implementation:alfa && npm run get:implementation:axe && npm run get:implementation:rgaa && npm run get:implementation:trustedTester", - "create:implementations:metrics": "node ./build/create-implementation-metrics", - "implementations": "npm run get:implementations && npm run create:implementations:metrics", - "create:testcases": "node ./build/create-testcases", - "create:glossary": "node ./build/create-glossary-usages", - "get:wcag:data": "node ./build/get-wcag-data", - "get:data": "npm run get:wcag:data && npm run create:testcases && npm run create:glossary && npm run implementations" + "pretest": "npm run getData", + "test": "jest --coverage" }, "homepage": "https://github.com/act-rules/act-rules.github.io", "repository": {