Merge pull request #1399 from NoRedInk/wat-592-elm-test

test with elm-test in buck2
This commit is contained in:
Brian Hicks 2023-05-31 18:30:22 -05:00 committed by GitHub
commit 010eb69d22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 331 additions and 21 deletions

23
BUCK
View File

@ -1,11 +1,20 @@
# A list of available rules and their signatures can be found here: https://buck2.build/docs/api/rules/
load("@prelude-nri//:elm.bzl", "elm_docs", "elm_format_diffs")
load("@prelude-nri//:elm.bzl", "elm_docs", "elm_format_diffs", "elm_test")
load("@prelude-nri//:node.bzl", "node_modules", "npm_bin", "npm_script_test", "prettier_diffs")
elm_docs(
name = "docs.json",
elm_json = "elm.json",
src = "src",
tests = [
":elm_test",
],
)
elm_test(
name = "elm_test",
test_srcs = glob(["tests/**/*.elm"]),
elm_test = ":elm_test_binary",
)
filegroup(
@ -39,6 +48,13 @@ npm_bin(
],
)
npm_bin(
name = "elm_test_binary",
bin_name = "elm-test",
node_modules = ":node_modules",
visibility = ["//component-catalog:elm_test"],
)
export_file(
name = "elm.json",
visibility = ["//component-catalog:public"],
@ -47,10 +63,11 @@ export_file(
npm_script_test(
name = "puppeteer",
node_modules = ":node_modules",
args = ["default", "$(location //component-catalog:public)"],
args = ["default", "public"],
extra_files = {
"script/puppeteer-tests.sh": "script/puppeteer-tests.sh",
"script/puppeteer-tests.js": "script/puppeteer-tests.js",
"public": "//component-catalog:public",
},
)
@ -69,6 +86,6 @@ genrule(
prettier_diffs(
name = "prettier_diffs",
srcs = glob(["**/*.md"]),
srcs = glob(["**/*.md", "script/**/*.js"]),
prettier = "//:prettier",
)

View File

@ -1,4 +1,4 @@
load("@prelude-nri//:elm.bzl", "elm_app", "elm_format_diffs")
load("@prelude-nri//:elm.bzl", "elm_app", "elm_format_diffs", "elm_test")
load("@prelude-nri//:node.bzl", "prettier_diffs")
elm_app(
@ -10,6 +10,15 @@ elm_app(
"../src": "//:src",
"src": "src",
},
tests = [
":elm_test",
],
)
elm_test(
name = "elm_test",
test_srcs = glob(["tests/**/*.elm"]),
elm_test = "//:elm_test_binary",
)
filegroup(

View File

@ -9,7 +9,7 @@
"elm/core": "1.0.5",
"elm/json": "1.1.3",
"elm/project-metadata-utils": "1.0.2",
"jfmengels/elm-review": "2.12.2",
"jfmengels/elm-review": "2.13.0",
"jfmengels/elm-review-unused": "1.1.29",
"stil4m/elm-syntax": "7.2.9"
},

View File

@ -113,9 +113,9 @@
"tesk9/palette": "3.0.1 <= v < 4.0.0"
},
"test-dependencies": {
"avh4/elm-program-test": "3.3.0 <= v < 4.0.0",
"avh4/elm-program-test": "4.0.0 <= v < 5.0.0",
"elm/html": "1.0.0 <= v < 2.0.0",
"elm-explorations/test": "1.2.2 <= v < 2.0.0",
"elm-explorations/test": "2.0.0 <= v < 3.0.0",
"tesk9/accessible-html": "5.0.0 <= v < 6.0.0"
}
}

View File

@ -11,10 +11,10 @@
"homepage": "https://github.com/nmattia/niv",
"owner": "nmattia",
"repo": "niv",
"rev": "82e5cd1ad3c387863f0545d7591512e76ab0fc41",
"sha256": "090l219mzc0gi33i3psgph6s2pwsc8qy4lyrqjdj4qzkvmaj65a7",
"rev": "7225521219f64df00de86c3b946a26f608f3b4dc",
"sha256": "04w9c06f70n0k9c4xhma4nfrkxxg7d039xd3v9dak8xd7avjb7v0",
"type": "tarball",
"url": "https://github.com/nmattia/niv/archive/82e5cd1ad3c387863f0545d7591512e76ab0fc41.tar.gz",
"url": "https://github.com/nmattia/niv/archive/7225521219f64df00de86c3b946a26f608f3b4dc.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixpkgs": {
@ -23,10 +23,10 @@
"homepage": "",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e2b34f0f11ed8ad83d9ec9c14260192c3bcccb0d",
"sha256": "1n9lhqprqnsiv4nw59mh5ab7hchx7lhvq43kkv64473jwz1xv7ki",
"rev": "7e0743a5aea1dc755d4b761daf75b20aa486fdad",
"sha256": "1zs1l3aivfwxmdrjvkiwqqj50z4yww5rx41m5b3qi6jv9pd9185r",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/e2b34f0f11ed8ad83d9ec9c14260192c3bcccb0d.tar.gz",
"url": "https://github.com/NixOS/nixpkgs/archive/7e0743a5aea1dc755d4b761daf75b20aa486fdad.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}
}

179
package-lock.json generated
View File

@ -17,6 +17,7 @@
"@percy/puppeteer": "^2.0.2",
"axe-core": "^4.7.0",
"browserify": "^17.0.0",
"elm-test": "0.19.1-revision12",
"expect": "29.5.0",
"mocha": "^10.2.0",
"prettier": "^2.7.1",
@ -1266,6 +1267,15 @@
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "9.5.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
"integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
"dev": true,
"engines": {
"node": "^12.20.0 || >=14"
}
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -1642,6 +1652,76 @@
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
"dev": true
},
"node_modules/elm-solve-deps-wasm": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/elm-solve-deps-wasm/-/elm-solve-deps-wasm-1.0.2.tgz",
"integrity": "sha512-qnwo7RO9IO7jd9SLHvIy0rSOEIlc/tNMTE9Cras0kl+b161PVidW4FvXo0MtXU8GAKi/2s/HYvhcnpR/NNQ1zw==",
"dev": true
},
"node_modules/elm-test": {
"version": "0.19.1-revision12",
"resolved": "https://registry.npmjs.org/elm-test/-/elm-test-0.19.1-revision12.tgz",
"integrity": "sha512-5GV3WkJ8R/faOP1hwElQdNuCt8tKx2+1lsMrdeIYWSFz01Kp9gJl/R6zGtp4QUyrUtO8KnHsxjHrQNUf2CHkrg==",
"dev": true,
"dependencies": {
"chalk": "^4.1.2",
"chokidar": "^3.5.3",
"commander": "^9.4.1",
"cross-spawn": "^7.0.3",
"elm-solve-deps-wasm": "^1.0.2",
"glob": "^8.0.3",
"graceful-fs": "^4.2.10",
"split": "^1.0.1",
"which": "^2.0.2",
"xmlbuilder": "^15.1.1"
},
"bin": {
"elm-test": "bin/elm-test"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/elm-test/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/elm-test/node_modules/glob": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^5.0.1",
"once": "^1.3.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/elm-test/node_modules/minimatch": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@ -3998,6 +4078,18 @@
"node": ">=0.10.0"
}
},
"node_modules/split": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
"integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
"dev": true,
"dependencies": {
"through": "2"
},
"engines": {
"node": "*"
}
},
"node_modules/sshpk": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
@ -4594,6 +4686,15 @@
}
}
},
"node_modules/xmlbuilder": {
"version": "15.1.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
"integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
"dev": true,
"engines": {
"node": ">=8.0"
}
},
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@ -5695,6 +5796,12 @@
"delayed-stream": "~1.0.0"
}
},
"commander": {
"version": "9.5.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
"integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -6016,6 +6123,63 @@
}
}
},
"elm-solve-deps-wasm": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/elm-solve-deps-wasm/-/elm-solve-deps-wasm-1.0.2.tgz",
"integrity": "sha512-qnwo7RO9IO7jd9SLHvIy0rSOEIlc/tNMTE9Cras0kl+b161PVidW4FvXo0MtXU8GAKi/2s/HYvhcnpR/NNQ1zw==",
"dev": true
},
"elm-test": {
"version": "0.19.1-revision12",
"resolved": "https://registry.npmjs.org/elm-test/-/elm-test-0.19.1-revision12.tgz",
"integrity": "sha512-5GV3WkJ8R/faOP1hwElQdNuCt8tKx2+1lsMrdeIYWSFz01Kp9gJl/R6zGtp4QUyrUtO8KnHsxjHrQNUf2CHkrg==",
"dev": true,
"requires": {
"chalk": "^4.1.2",
"chokidar": "^3.5.3",
"commander": "^9.4.1",
"cross-spawn": "^7.0.3",
"elm-solve-deps-wasm": "^1.0.2",
"glob": "^8.0.3",
"graceful-fs": "^4.2.10",
"split": "^1.0.1",
"which": "^2.0.2",
"xmlbuilder": "^15.1.1"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0"
}
},
"glob": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^5.0.1",
"once": "^1.3.0"
}
},
"minimatch": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"
}
}
}
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@ -7797,6 +7961,15 @@
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
"dev": true
},
"split": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
"integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
"dev": true,
"requires": {
"through": "2"
}
},
"sshpk": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
@ -8293,6 +8466,12 @@
"dev": true,
"requires": {}
},
"xmlbuilder": {
"version": "15.1.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
"integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
"dev": true
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

View File

@ -32,6 +32,7 @@
"@percy/puppeteer": "^2.0.2",
"axe-core": "^4.7.0",
"browserify": "^17.0.0",
"elm-test": "0.19.1-revision12",
"expect": "29.5.0",
"mocha": "^10.2.0",
"prettier": "^2.7.1",

View File

@ -154,4 +154,47 @@ elm_format_diffs = rule(
providers = [ElmToolchainInfo],
),
}
)
def _elm_test_impl(ctx: "context") -> [[DefaultInfo.type, ExternalRunnerTestInfo.type]]:
command = [
ctx.attrs._python_toolchain[PythonToolchainInfo].interpreter,
cmd_args(ctx.attrs._elm_toolchain[ElmToolchainInfo].elm_test_workdir[DefaultInfo].default_outputs),
"--elm-test-binary",
ctx.attrs.elm_test[RunInfo] if ctx.attrs.elm_test else "elm-test",
ctx.label.package or '.',
cmd_args(ctx.attrs._elm_toolchain.get(ElmToolchainInfo).elm, format="--compiler={}"),
cmd_args(str(ctx.attrs.fuzz), format="--fuzz={}"),
]
if ctx.attrs.seed:
command.append(cmd_args(ctx.attrs.seed, format="--seed={}"))
command.extend(ctx.attrs.test_srcs)
return [
DefaultInfo(),
ExternalRunnerTestInfo(
type = "elm_test",
command = command,
use_project_relative_paths = False,
),
]
elm_test = rule(
impl = _elm_test_impl,
attrs = {
"test_srcs": attrs.list(attrs.source()),
"fuzz": attrs.int(default=100),
"seed": attrs.option(attrs.string(), default=None),
"elm_test": attrs.option(attrs.exec_dep(), default=None),
"_elm_toolchain": attrs.toolchain_dep(
default = "toolchains//:elm",
providers = [ElmToolchainInfo],
),
"_python_toolchain": attrs.toolchain_dep(
default = "toolchains//:python",
providers = [PythonToolchainInfo],
),
},
)

View File

@ -3,6 +3,11 @@ export_file(
visibility = ["PUBLIC"],
)
export_file(
name = "elm_test_workdir.py",
visibility = ["PUBLIC"],
)
ELM_COMPILER_URL = select({
"config//os:linux": "https://github.com/elm/compiler/releases/download/0.19.1/binary-for-linux-64-bit.gz",
"config//os:macos": "https://github.com/elm/compiler/releases/download/0.19.1/binary-for-mac-64-bit.gz",
@ -24,6 +29,7 @@ genrule(
cmd = "gzip --decompress --stdout --keep $(location :elm_compiler_archive) > $OUT && chmod +x $OUT",
out = "elm",
executable = True,
remote = True,
visibility = ["PUBLIC"],
)
@ -54,5 +60,6 @@ genrule(
out = "elm-format",
cmd = "cp $(location :elm_format_archive)/elm-format $OUT",
executable = True,
remote = True,
visibility = ["PUBLIC"],
)

View File

@ -0,0 +1,27 @@
#!/usr/bin/env python
import argparse
import subprocess
import sys
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"root", help="Where to change directory to before running elm-test"
)
parser.add_argument(
"--elm-test-binary",
default="elm-test",
help="The binary to invoke for elm-test",
)
parser.add_argument(
"elm_test_args",
nargs=argparse.REMAINDER,
help="Args to be passed on to elm-test",
)
args = parser.parse_args()
returncode = subprocess.call(
[args.elm_test_binary] + args.elm_test_args, cwd=args.root
)
sys.exit(returncode)

View File

@ -1,7 +1,8 @@
ElmToolchainInfo = provider(fields = [
"elm",
"isolated_compile",
"elm_format",
"isolated_compile",
"elm_test_workdir",
])
def _system_elm_toolchain_impl(ctx) -> [[DefaultInfo.type, ElmToolchainInfo.type]]:
@ -15,6 +16,7 @@ def _system_elm_toolchain_impl(ctx) -> [[DefaultInfo.type, ElmToolchainInfo.type
elm = RunInfo(args = ["elm"]),
elm_format = RunInfo(args = ["elm-format"]),
isolated_compile = ctx.attrs._isolated_compile,
elm_test_workdir = ctx.attrs._elm_test_workdir,
),
]
@ -22,6 +24,7 @@ system_elm_toolchain = rule(
impl = _system_elm_toolchain_impl,
attrs = {
"_isolated_compile": attrs.dep(default = "prelude-nri//elm:isolated_compile.py"),
"_elm_test_workdir": attrs.dep(default = "prelude-nri//elm:elm_test_workdir.py"),
},
is_toolchain_rule = True,
)
@ -37,21 +40,23 @@ def _elm_toolchain_impl(ctx: "context") -> [[DefaultInfo.type, ElmToolchainInfo.
elm = ctx.attrs.elm[RunInfo],
elm_format = ctx.attrs.elm_format[RunInfo],
isolated_compile = ctx.attrs._isolated_compile,
elm_test_workdir = ctx.attrs._elm_test_workdir,
),
]
elm_toolchain = rule(
impl = _elm_toolchain_impl,
attrs = {
"elm": attrs.dep(
"elm": attrs.exec_dep(
providers = [RunInfo],
default = "prelude-nri//elm:elm_compiler_binary",
),
"elm_format": attrs.dep(
"elm_format": attrs.exec_dep(
providers = [RunInfo],
default = "prelude-nri//elm:elm_format_binary",
),
"_isolated_compile": attrs.dep(default = "prelude-nri//elm:isolated_compile.py"),
"_elm_test_workdir": attrs.dep(default = "prelude-nri//elm:elm_test_workdir.py"),
},
is_toolchain_rule = True,
)

View File

@ -127,6 +127,7 @@ def _npm_script_test_impl(ctx: "context") -> [[DefaultInfo.type, ExternalRunnerT
ExternalRunnerTestInfo(
type = "npm",
command = cmd,
use_project_relative_paths = False,
),
DefaultInfo(),
]

View File

@ -9,7 +9,7 @@
"elm/core": "1.0.5",
"elm/json": "1.1.3",
"elm/project-metadata-utils": "1.0.2",
"jfmengels/elm-review": "2.12.2",
"jfmengels/elm-review": "2.13.0",
"jfmengels/elm-review-unused": "1.1.29",
"stil4m/elm-syntax": "7.2.9"
},

View File

@ -1,4 +1,5 @@
const expect = require("expect");
const fs = require("fs");
const puppeteer = require("puppeteer");
const httpServer = require("http-server");
const percySnapshot = require("@percy/puppeteer");
@ -17,9 +18,21 @@ describe("UI tests", function () {
let browser;
before(async () => {
server = httpServer.createServer({
root: process.env.ROOT || `${__dirname}/../public`,
});
let root = process.env.ROOT || `${__dirname}/../public`;
if (!fs.existsSync(root)) {
assert.fail(
`Root was specified as ${root}, but that path does not exist.`
);
}
if (!fs.existsSync(`${root}/index.html`)) {
assert.fail(
`Root was specified as ${root}, but does not contain an index.html.`
);
}
server = httpServer.createServer({ root });
server.listen(PORT);
browser = await puppeteer.launch({
@ -33,6 +46,12 @@ describe("UI tests", function () {
server.close();
});
const handlePageErrors = function (page) {
page.on("pageerror", (err) => {
console.log("Error from page:", err.toString());
});
};
const handleAxeResults = function (name, results) {
const violations = results["violations"];
if (violations.length > 0) {
@ -188,7 +207,8 @@ describe("UI tests", function () {
it("All", async function () {
page = await browser.newPage();
await page.goto(`http://localhost:${PORT}`);
handlePageErrors(page);
await page.goto(`http://localhost:${PORT}`, { waitUntil: "load" });
await page.$("#maincontent");
await percySnapshot(page, this.test.fullTitle());
@ -208,6 +228,7 @@ describe("UI tests", function () {
it("Doodads", async function () {
page = await browser.newPage();
handlePageErrors(page);
await page.goto(`http://localhost:${PORT}`);
await page.$("#maincontent");