Merge pull request #936 from NoRedInk/prettier

enforce JS style with prettier
This commit is contained in:
Brian Hicks 2022-05-26 16:10:51 -05:00 committed by GitHub
commit f86fdd49fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 4970 additions and 294 deletions

View File

@ -106,11 +106,23 @@ main = do
cmd (WithStdout True) (FileStdout out) "elm-verify-examples"
"log/format.txt" %> \out -> do
need ["log/elm-format.txt", "log/prettier.txt"]
writeFileChanged out "formatting checks passed"
"log/elm-format.txt" %> \out -> do
let placesToLook = ["src", "tests", "styleguide", "styleguide-app"]
elmFiles <- getDirectoryFiles "." (map (\place -> place </> "**" </> "*.elm") placesToLook)
need elmFiles
cmd (WithStdout True) (FileStdout out) "elm-format" "--validate" placesToLook
"log/prettier.txt" %> \out -> do
(Stdout trackedFilesOut) <- cmd "git" "ls-files"
let trackedFiles = lines trackedFilesOut
let jsFiles = filter (\name -> takeExtension name == ".js") trackedFiles
need ("log/npm-install.txt" : jsFiles)
cmd (WithStdout True) (FileStdout out) "./node_modules/.bin/prettier" "--check" jsFiles
"log/puppeteer-tests.txt" %> \out -> do
percyToken <- getEnv "PERCY_TOKEN"
case percyToken of

View File

@ -2,8 +2,7 @@
* @module CustomElement
*/
/**
/**
* Create a DOM Event without worrying about browser compatibility
*
* @param {string} eventName The name of the event to create
@ -13,9 +12,9 @@
* var event = CustomElement.makeEvent('change', { name: this._secretInput.value })
* this.dispatchEvent(event)
*/
exports.makeEvent = makeMakeEvent()
exports.makeEvent = makeMakeEvent();
var makeClass = makeMakeClass()
var makeClass = makeMakeClass();
function noOp() {}
@ -45,19 +44,19 @@ function noOp() {}
* this._button = document.createElement('button')
* },
*
* // Let the custom element runtime know that you want to be notified of
* // changes to the `hello` attribute
* observedAttributes: ['hello'],
* // Let the custom element runtime know that you want to be notified of
* // changes to the `hello` attribute
* observedAttributes: ['hello'],
*
* // Do any updating when an attribute changes on the element. Note the
* // difference between attributes and properties of an element (see:
* // https://javascript.info/dom-attributes-and-properties). This is a
* // proxy for `attributeChangedCallback` (see:
* // https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#Using_the_lifecycle_callbacks).
* // Takes the name of the attribute that changed, the previous string value,
* // and the new string value.
* onAttributeChange: function(name, previous, next) {
* if (name === 'hello') this._hello = next
* // Do any updating when an attribute changes on the element. Note the
* // difference between attributes and properties of an element (see:
* // https://javascript.info/dom-attributes-and-properties). This is a
* // proxy for `attributeChangedCallback` (see:
* // https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#Using_the_lifecycle_callbacks).
* // Takes the name of the attribute that changed, the previous string value,
* // and the new string value.
* onAttributeChange: function(name, previous, next) {
* if (name === 'hello') this._hello = next
* },
*
* // Do any setup work after the element has been inserted into the DOM.
@ -109,38 +108,42 @@ function noOp() {}
*/
exports.create = function create(config) {
if (customElements.get(config.tagName)) {
throw Error('Custom element with tag name ' + config.tagName + ' already exists.')
throw Error(
"Custom element with tag name " + config.tagName + " already exists."
);
}
var observedAttributes = config.observedAttributes || []
var methods = config.methods || {}
var properties = config.properties || {}
var initialize = config.initialize || noOp
var onConnect = config.onConnect || noOp
var onDisconnect = config.onDisconnect || noOp
var onAttributeChange = config.onAttributeChange || noOp
var observedAttributes = config.observedAttributes || [];
var methods = config.methods || {};
var properties = config.properties || {};
var initialize = config.initialize || noOp;
var onConnect = config.onConnect || noOp;
var onDisconnect = config.onDisconnect || noOp;
var onAttributeChange = config.onAttributeChange || noOp;
var Class = makeClass();
var Class = makeClass()
for (var key in methods) {
if (!methods.hasOwnProperty(key)) continue
Class.prototype[key] = methods[key]
if (!methods.hasOwnProperty(key)) continue;
Class.prototype[key] = methods[key];
}
Object.defineProperties(Class.prototype, properties)
Object.defineProperties(Class.prototype, properties);
Class.prototype.connectedCallback = onConnect
Class.prototype.disconnectedCallback = onDisconnect
Class.prototype.attributeChangedCallback = onAttributeChange
Class.prototype.connectedCallback = onConnect;
Class.prototype.disconnectedCallback = onDisconnect;
Class.prototype.attributeChangedCallback = onAttributeChange;
if (Array.isArray(observedAttributes)) {
Object.defineProperty(Class, 'observedAttributes', {
get: function () { return observedAttributes }
})
Object.defineProperty(Class, "observedAttributes", {
get: function () {
return observedAttributes;
},
});
}
Class.displayName = '<' + config.tagName + '> custom element'
customElements.define(config.tagName, Class)
}
Class.displayName = "<" + config.tagName + "> custom element";
customElements.define(config.tagName, Class);
};
/**
* Attempt to make an ES6 class using the Function constructor rather than
@ -151,35 +154,37 @@ exports.create = function create(config) {
*/
function makeMakeClass() {
try {
return new Function([
"return class extends HTMLElement {",
" constructor() {",
" super()",
" for (var key in this) {",
" var value = this[key]",
" if (typeof value !== 'function') continue",
" this[key] = value.bind(this)",
" }",
" }",
"}",
].join("\n"))
return new Function(
[
"return class extends HTMLElement {",
" constructor() {",
" super()",
" for (var key in this) {",
" var value = this[key]",
" if (typeof value !== 'function') continue",
" this[key] = value.bind(this)",
" }",
" }",
"}",
].join("\n")
);
} catch (e) {
return function () {
function Class() {
// This is the best we can do to trick modern browsers into thinking this
// is a real, legitimate class constructor and not a plane old JS function.
var _this = HTMLElement.call(this) || this
var _this = HTMLElement.call(this) || this;
for (var key in _this) {
var value = _this[key]
if (typeof value !== 'function') continue
_this[key] = value.bind(_this)
var value = _this[key];
if (typeof value !== "function") continue;
_this[key] = value.bind(_this);
}
return _this
return _this;
}
Class.prototype = Object.create(HTMLElement.prototype)
Class.prototype.constructor = Class
return Class
}
Class.prototype = Object.create(HTMLElement.prototype);
Class.prototype.constructor = Class;
return Class;
};
}
}
@ -187,20 +192,20 @@ function makeMakeClass() {
* Return a function for making an event based on what the browser supports.
* IE11 doesn't support Event constructor, and uses the old Java-style
* methods instead
*/
*/
function makeMakeEvent() {
try {
// if calling Event with new works, do it that way
var testEvent = new CustomEvent('myEvent', { detail: 1 })
var testEvent = new CustomEvent("myEvent", { detail: 1 });
return function makeEventNewStyle(type, detail) {
return new CustomEvent(type, { detail: detail })
}
return new CustomEvent(type, { detail: detail });
};
} catch (_error) {
// if calling CustomEvent with new throws an error, do it the old way
return function makeEventOldStyle(type, detail) {
var event = document.createEvent('CustomEvent')
event.initCustomEvent(type, false, false, detail)
return event
}
var event = document.createEvent("CustomEvent");
event.initCustomEvent(type, false, false, detail);
return event;
};
}
}

View File

@ -1,57 +1,63 @@
CustomElement = require('../CustomElement')
CustomElement = require("../CustomElement");
CustomElement.create({
tagName: 'nri-textarea-v3',
tagName: "nri-textarea-v3",
initialize: function() {
this._autoresize = false
initialize: function () {
this._autoresize = false;
},
onConnect: function() {
this._textarea = this.querySelector('textarea')
this._updateListener()
onConnect: function () {
this._textarea = this.querySelector("textarea");
this._updateListener();
},
observedAttributes: ['data-autoresize'],
observedAttributes: ["data-autoresize"],
onAttributeChange: function(name, previous, next) {
if (name === 'data-autoresize') {
this._autoresize = next !== null
if (!this._textarea) return
this._updateListener()
onAttributeChange: function (name, previous, next) {
if (name === "data-autoresize") {
this._autoresize = next !== null;
if (!this._textarea) return;
this._updateListener();
}
},
methods: {
_updateListener: function() {
_updateListener: function () {
if (this._autoresize) {
this._textarea.addEventListener('input', this._resize)
this._resize()
this._textarea.addEventListener("input", this._resize);
this._resize();
} else {
this._textarea.removeEventListener('input', this._resize)
this._textarea.removeEventListener("input", this._resize);
}
},
_resize: function() {
var minHeight = null
_resize: function () {
var minHeight = null;
if (this._textarea.style.minHeight) {
minHeight = parseInt(this._textarea.style.minHeight, 10)
minHeight = parseInt(this._textarea.style.minHeight, 10);
} else {
minHeight = parseInt(window.getComputedStyle(this._textarea).minHeight, 10)
minHeight = parseInt(
window.getComputedStyle(this._textarea).minHeight,
10
);
}
if (minHeight === 0) {
minHeight = parseInt(window.getComputedStyle(this._textarea).height, 10)
minHeight = parseInt(
window.getComputedStyle(this._textarea).height,
10
);
}
this._textarea.style.overflowY = 'hidden'
this._textarea.style.minHeight = minHeight + 'px'
this._textarea.style.transition = 'none'
this._textarea.style.overflowY = "hidden";
this._textarea.style.minHeight = minHeight + "px";
this._textarea.style.transition = "none";
if (this._textarea.scrollHeight > minHeight) {
this._textarea.style.height = minHeight + 'px'
this._textarea.style.height = this._textarea.scrollHeight + 'px'
this._textarea.style.height = minHeight + "px";
this._textarea.style.height = this._textarea.scrollHeight + "px";
} else {
this._textarea.style.height = minHeight + 'px'
this._textarea.style.height = minHeight + "px";
}
}
}
})
},
},
});

View File

@ -1,63 +1,67 @@
CustomElement = require('../CustomElement')
CustomElement = require("../CustomElement");
CustomElement.create({
tagName: 'nri-textarea-v4',
tagName: "nri-textarea-v4",
initialize: function() {
this._autoresize = false
initialize: function () {
this._autoresize = false;
},
onConnect: function() {
this._textarea = this.querySelector('textarea')
this._updateListener()
onConnect: function () {
this._textarea = this.querySelector("textarea");
this._updateListener();
},
observedAttributes: ['data-autoresize'],
observedAttributes: ["data-autoresize"],
onAttributeChange: function(name, previous, next) {
if (name === 'data-autoresize') {
this._autoresize = next !== null
if (!this._textarea) return
this._updateListener()
onAttributeChange: function (name, previous, next) {
if (name === "data-autoresize") {
this._autoresize = next !== null;
if (!this._textarea) return;
this._updateListener();
}
},
methods: {
_updateListener: function() {
_updateListener: function () {
if (this._autoresize) {
this._textarea.addEventListener('input', this._resize)
this._resize()
this._textarea.addEventListener("input", this._resize);
this._resize();
} else {
this._textarea.removeEventListener('input', this._resize)
this._textarea.removeEventListener("input", this._resize);
}
},
_resize: function() {
_resize: function () {
var minHeight = null;
var computedStyles = window.getComputedStyle(this._textarea);
if (this._textarea.style.minHeight) {
minHeight = parseInt(this._textarea.style.minHeight, 10)
minHeight = parseInt(this._textarea.style.minHeight, 10);
} else {
minHeight = parseInt(computedStyles.minHeight, 10)
}
if (minHeight === 0) {
minHeight = parseInt(computedStyles.height, 10)
minHeight = parseInt(computedStyles.minHeight, 10);
}
this._textarea.style.overflowY = 'hidden'
this._textarea.style.minHeight = minHeight + 'px'
this._textarea.style.transition = 'none'
if (minHeight === 0) {
minHeight = parseInt(computedStyles.height, 10);
}
this._textarea.style.overflowY = "hidden";
this._textarea.style.minHeight = minHeight + "px";
this._textarea.style.transition = "none";
// the browser does not include border widths in `.scrollHeight`, but we
// sometimes use `box-sizing: border-box` on these elements so we need to
// take it into account when setting the CSS `height`.
var borderOffset = 0;
if (computedStyles.boxSizing === 'border-box') {
borderOffset = parseInt(computedStyles.borderTopWidth, 10) + parseInt(computedStyles.borderBottomWidth, 10);
if (computedStyles.boxSizing === "border-box") {
borderOffset =
parseInt(computedStyles.borderTopWidth, 10) +
parseInt(computedStyles.borderBottomWidth, 10);
}
this._textarea.style.height = Math.max(minHeight, this._textarea.scrollHeight + borderOffset) + 'px'
}
}
})
this._textarea.style.height =
Math.max(minHeight, this._textarea.scrollHeight + borderOffset) + "px";
},
},
});

View File

@ -1,4 +1,4 @@
require('./TextArea/V3')
require('./TextArea/V4')
require("./TextArea/V3");
require("./TextArea/V4");
exports.CustomElement = require('./CustomElement')
exports.CustomElement = require("./CustomElement");

View File

@ -2,7 +2,7 @@
"elm-forbid-import": {
"branch": "main",
"repo": "https://git.bytes.zone/brian/elm-forbid-import.git",
"rev": "e4514ed0c0c267aa5f192bdc0956b0846ade5e2c",
"rev": "f5d5dc93bb68a58aaa922ba588c94941845e0941",
"type": "git"
},
"niv": {
@ -11,22 +11,22 @@
"homepage": "https://github.com/nmattia/niv",
"owner": "nmattia",
"repo": "niv",
"rev": "e0ca65c81a2d7a4d82a189f1e23a48d59ad42070",
"sha256": "1pq9nh1d8nn3xvbdny8fafzw87mj7gsmp6pxkdl65w2g18rmcmzx",
"rev": "82e5cd1ad3c387863f0545d7591512e76ab0fc41",
"sha256": "090l219mzc0gi33i3psgph6s2pwsc8qy4lyrqjdj4qzkvmaj65a7",
"type": "tarball",
"url": "https://github.com/nmattia/niv/archive/e0ca65c81a2d7a4d82a189f1e23a48d59ad42070.tar.gz",
"url": "https://github.com/nmattia/niv/archive/82e5cd1ad3c387863f0545d7591512e76ab0fc41.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixpkgs": {
"branch": "release-21.05",
"branch": "nixpkgs-unstable",
"description": "Nix Packages collection",
"homepage": "",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1dc32d71d5d8fe18ff13f31488fafc1d9145f886",
"sha256": "1pgmg0sqyrk3a4gfm1lqv9wmn5pxlivqmblhls7hig9db08brni6",
"rev": "41cc1d5d9584103be4108c1815c350e07c807036",
"sha256": "1zwbkijhgb8a5wzsm1dya1a4y79bz6di5h49gcmw6klai84xxisv",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/1dc32d71d5d8fe18ff13f31488fafc1d9145f886.tar.gz",
"url": "https://github.com/NixOS/nixpkgs/archive/41cc1d5d9584103be4108c1815c350e07c807036.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}
}

View File

@ -31,8 +31,28 @@ let
if spec ? branch then "refs/heads/${spec.branch}" else
if spec ? tag then "refs/tags/${spec.tag}" else
abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!";
submodules = if spec ? submodules then spec.submodules else false;
submoduleArg =
let
nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0;
emptyArgWithWarning =
if submodules == true
then
builtins.trace
(
"The niv input \"${name}\" uses submodules "
+ "but your nix's (${builtins.nixVersion}) builtins.fetchGit "
+ "does not support them"
)
{}
else {};
in
if nixSupportsSubmodules
then { inherit submodules; }
else emptyArgWithWarning;
in
builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; };
builtins.fetchGit
({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg);
fetch_local = spec: spec.path;

4771
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
"@percy/cli": "^1.0.0-beta.73",
"@percy/puppeteer": "^2.0.0",
"browserify": "16.2.3",
"prettier": "^2.6.2",
"puppeteer": "^3.3.0",
"request": "^2.88.0"
},

4
script/prettier-fix-all.sh Executable file
View File

@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail
git ls-files | grep -E '.js$' | xargs node_modules/.bin/prettier --write

View File

@ -1,17 +1,17 @@
const expect = require('expect');
const puppeteer = require('puppeteer');
const httpServer = require('http-server');
const percySnapshot = require('@percy/puppeteer');
const expect = require("expect");
const puppeteer = require("puppeteer");
const httpServer = require("http-server");
const percySnapshot = require("@percy/puppeteer");
const platform = require('os').platform();
const platform = require("os").platform();
// We need to change the args passed to puppeteer based on the platform they're using
const puppeteerArgs = /^win/.test(platform) ? [] : ['--single-process'];
const puppeteerArgs = /^win/.test(platform) ? [] : ["--single-process"];
const PORT = process.env.PORT_NUMBER || 8000;
const { AxePuppeteer } = require('@axe-core/puppeteer');
const assert = require('assert');
const { AxePuppeteer } = require("@axe-core/puppeteer");
const assert = require("assert");
describe('UI tests', function () {
describe("UI tests", function () {
let page;
let server;
let browser;
@ -23,7 +23,7 @@ describe('UI tests', function () {
browser = await puppeteer.launch({
headless: true,
timeout: 10000,
args: puppeteerArgs
args: puppeteerArgs,
});
});
@ -31,113 +31,126 @@ describe('UI tests', function () {
server.close();
});
const handleAxeResults = function(name, results) {
const handleAxeResults = function (name, results) {
const violations = results["violations"];
if (violations.length > 0) {
violations.map(function(violation) {
console.log("\n\n", violation["id"], ":", violation["description"])
console.log(violation["help"])
console.log(violation["helpUrl"])
violations.map(function (violation) {
console.log("\n\n", violation["id"], ":", violation["description"]);
console.log(violation["help"]);
console.log(violation["helpUrl"]);
console.table(violation["nodes"], ["html"])
console.table(violation["nodes"], ["html"]);
});
assert.fail(`Expected no axe violations in ${name} but got ${violations.length} violations`)
assert.fail(
`Expected no axe violations in ${name} but got ${violations.length} violations`
);
}
}
};
const defaultProcessing = async (name, location) => {
await page.goto(location)
await page.waitFor(`#${name.replace(".", "-")}`)
await percySnapshot(page, name)
await page.goto(location);
await page.waitFor(`#${name.replace(".", "-")}`);
await percySnapshot(page, name);
const results = await new AxePuppeteer(page).disableRules(skippedRules[name] || []).analyze();
const results = await new AxePuppeteer(page)
.disableRules(skippedRules[name] || [])
.analyze();
handleAxeResults(name, results);
}
};
const iconProcessing = async(name, location) => {
await page.goto(location)
await page.waitFor(`#${name}`)
await percySnapshot(page, name)
const iconProcessing = async (name, location) => {
await page.goto(location);
await page.waitFor(`#${name}`);
await percySnapshot(page, name);
// visible icon names snapshot
await page.click("label");
await page.waitForSelector(".checkbox-V5__Checked")
await percySnapshot(page, `${name} - display icon names`)
await page.waitForSelector(".checkbox-V5__Checked");
await percySnapshot(page, `${name} - display icon names`);
const results = await new AxePuppeteer(page).disableRules(skippedRules[name] || []).analyze();
const results = await new AxePuppeteer(page)
.disableRules(skippedRules[name] || [])
.analyze();
handleAxeResults(name, results);
}
};
const skippedRules = {
// Loading's color contrast check seems to change behavior depending on whether Percy snapshots are taken or not
'Loading': ['color-contrast'],
'RadioButton': ['duplicate-id'],
}
Loading: ["color-contrast"],
RadioButton: ["duplicate-id"],
};
const specialProcessing = {
'Modal': async (name, location) => {
await page.goto(location)
await page.waitFor(`#${name}`)
await page.click('#launch-modal')
await page.waitFor('[role="dialog"]')
await percySnapshot(page, 'Full Info Modal')
Modal: async (name, location) => {
await page.goto(location);
await page.waitFor(`#${name}`);
await page.click("#launch-modal");
await page.waitFor('[role="dialog"]');
await percySnapshot(page, "Full Info Modal");
const results = await new AxePuppeteer(page).disableRules(skippedRules[name] || []).analyze();
const results = await new AxePuppeteer(page)
.disableRules(skippedRules[name] || [])
.analyze();
handleAxeResults(name, results);
await page.click('[aria-label="Close modal"]')
await page.select('select', 'warning')
await page.click('#launch-modal')
await page.waitFor('[role="dialog"]')
await percySnapshot(page, 'Full Warning Modal')
await page.click('[aria-label="Close modal"]')
await page.click('[aria-label="Close modal"]');
await page.select("select", "warning");
await page.click("#launch-modal");
await page.waitFor('[role="dialog"]');
await percySnapshot(page, "Full Warning Modal");
await page.click('[aria-label="Close modal"]');
},
'AssignmentIcon': iconProcessing,
'UiIcon': iconProcessing,
'Logo': iconProcessing,
'Pennant': iconProcessing
}
AssignmentIcon: iconProcessing,
UiIcon: iconProcessing,
Logo: iconProcessing,
Pennant: iconProcessing,
};
it('All', async function () {
it("All", async function () {
page = await browser.newPage();
await page.goto(`http://localhost:${PORT}`);
await page.$('#maincontent');
await page.$("#maincontent");
await percySnapshot(page, this.test.fullTitle());
const results = await new AxePuppeteer(page).
disableRules([
const results = await new AxePuppeteer(page)
.disableRules([
"aria-hidden-focus",
"color-contrast",
"duplicate-id-aria",
"duplicate-id",
]).analyze();
])
.analyze();
page.close();
handleAxeResults("index view", results);
});
it('Doodads', async function () {
it("Doodads", async function () {
page = await browser.newPage();
await page.goto(`http://localhost:${PORT}`);
await page.$('#maincontent');
await page.$("#maincontent");
let links = await page.evaluate(() => {
let nodes = Array.from(document.querySelectorAll("[data-nri-description='doodad-link']"));
return nodes.map(node => [node.text, node.href])
})
let nodes = Array.from(
document.querySelectorAll("[data-nri-description='doodad-link']")
);
return nodes.map((node) => [node.text, node.href]);
});
await links.reduce((acc, [name, location]) => {
return acc.then(() => {
if (process.env.ONLYDOODAD == "default" || process.env.ONLYDOODAD == name) {
console.log(`Testing ${name}`)
if (
process.env.ONLYDOODAD == "default" ||
process.env.ONLYDOODAD == name
) {
console.log(`Testing ${name}`);
let handler = specialProcessing[name] || defaultProcessing;
return handler(name, location);
}
})
}, Promise.resolve())
});
}, Promise.resolve());
page.close();
})
});
});
});

View File

@ -5,7 +5,7 @@ let
else
builtins.currentSystem;
nixpkgs = import sources.nixpkgs { inherit system; };
niv = nixpkgs.callPackage sources.niv { };
niv = import sources.niv { };
in with nixpkgs;
stdenv.mkDerivation {
name = "noredink-ui";

View File

@ -1 +1 @@
require('../lib/index.js');
require("../lib/index.js");