qunitx-cli 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/servers/http.js +6 -2
- package/package.json +1 -1
- package/.claude/settings.local.json +0 -7
- package/.env +0 -1
- package/Makefile +0 -35
- package/cliff.toml +0 -23
- package/demo/demo.gif +0 -0
- package/demo/demo.tape +0 -59
- package/demo/example-test.js +0 -53
- package/demo/failing-test.js +0 -22
- package/flake.lock +0 -64
- package/flake.nix +0 -55
package/lib/servers/http.js
CHANGED
|
@@ -133,10 +133,14 @@ export default class HTTPServer {
|
|
|
133
133
|
|
|
134
134
|
handleRequest(req, res) {
|
|
135
135
|
const { method, url } = req;
|
|
136
|
-
const
|
|
136
|
+
const urlObj = new URL(url, 'http://localhost');
|
|
137
|
+
const pathname = urlObj.pathname;
|
|
138
|
+
req.path = pathname;
|
|
139
|
+
req.query = Object.fromEntries(urlObj.searchParams);
|
|
140
|
+
const matchingRoute = this.findRouteHandler(method, pathname);
|
|
137
141
|
|
|
138
142
|
if (matchingRoute) {
|
|
139
|
-
req.params = this.extractParams(matchingRoute,
|
|
143
|
+
req.params = this.extractParams(matchingRoute, pathname);
|
|
140
144
|
this.runMiddleware(req, res, matchingRoute.handler);
|
|
141
145
|
} else {
|
|
142
146
|
res.statusCode = 404;
|
package/package.json
CHANGED
package/.env
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export CHROME_BIN=$(which google-chrome-stable)
|
package/Makefile
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
.PHONY: check test lint build demo release
|
|
2
|
-
|
|
3
|
-
check: lint test
|
|
4
|
-
|
|
5
|
-
lint:
|
|
6
|
-
npm run lint
|
|
7
|
-
|
|
8
|
-
test:
|
|
9
|
-
npm test
|
|
10
|
-
|
|
11
|
-
build:
|
|
12
|
-
npm run build
|
|
13
|
-
|
|
14
|
-
# Regenerate demo/demo.gif using VHS.
|
|
15
|
-
# Requires: vhs (brew install vhs | nix profile install nixpkgs#vhs)
|
|
16
|
-
# Chrome (google-chrome-stable or chromium)
|
|
17
|
-
demo:
|
|
18
|
-
@which vhs > /dev/null 2>&1 || (echo "vhs not found — install: brew install vhs or nix profile install nixpkgs#vhs" && exit 1)
|
|
19
|
-
@CHROME=$$(which google-chrome-stable 2>/dev/null || which google-chrome 2>/dev/null || which chromium 2>/dev/null); \
|
|
20
|
-
test -n "$$CHROME" || (echo "Chrome not found — install google-chrome-stable or chromium" && exit 1); \
|
|
21
|
-
CHROME_BIN=$$CHROME vhs demo/demo.tape
|
|
22
|
-
|
|
23
|
-
# Lint, bump version, update changelog, commit, tag, push, publish to npm.
|
|
24
|
-
# CI then pushes the versioned Docker image and creates the GitHub release.
|
|
25
|
-
# Usage: make release LEVEL=patch|minor|major
|
|
26
|
-
release:
|
|
27
|
-
@test -n "$(LEVEL)" || (echo "Usage: make release LEVEL=patch|minor|major" && exit 1)
|
|
28
|
-
npm run lint
|
|
29
|
-
npm version $(LEVEL) --no-git-tag-version
|
|
30
|
-
npm run changelog:update
|
|
31
|
-
git add package.json package-lock.json CHANGELOG.md
|
|
32
|
-
git commit -m "Release $$(node -p 'require("./package.json").version')"
|
|
33
|
-
git tag "v$$(node -p 'require("./package.json").version')"
|
|
34
|
-
git push && git push --tags
|
|
35
|
-
npm publish --access public
|
package/cliff.toml
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
[changelog]
|
|
2
|
-
header = """# Changelog
|
|
3
|
-
|
|
4
|
-
All notable changes to this project will be documented in this file.
|
|
5
|
-
"""
|
|
6
|
-
body = """
|
|
7
|
-
{% if version %}\
|
|
8
|
-
## {{ version | trim_start_matches(pat="v") }} — {{ timestamp | date(format="%Y-%m-%d") }}
|
|
9
|
-
{% else %}\
|
|
10
|
-
## Unreleased
|
|
11
|
-
{% endif %}\
|
|
12
|
-
{% for commit in commits %}\
|
|
13
|
-
- {{ commit.message | split(pat="\n") | first | trim | upper_first }}
|
|
14
|
-
{% endfor %}
|
|
15
|
-
"""
|
|
16
|
-
footer = ""
|
|
17
|
-
trim = true
|
|
18
|
-
|
|
19
|
-
[git]
|
|
20
|
-
conventional_commits = false
|
|
21
|
-
filter_unconventional = false
|
|
22
|
-
tag_pattern = "v[0-9].*"
|
|
23
|
-
sort_commits = "newest"
|
package/demo/demo.gif
DELETED
|
Binary file
|
package/demo/demo.tape
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# qunitx-cli demo — generates demo/demo.gif
|
|
2
|
-
# Run via: make demo (handles Chrome discovery automatically)
|
|
3
|
-
|
|
4
|
-
Output demo/demo.gif
|
|
5
|
-
|
|
6
|
-
Set Shell bash
|
|
7
|
-
Set FontSize 15
|
|
8
|
-
Set Width 800
|
|
9
|
-
Set Height 750
|
|
10
|
-
Set Theme "Dracula"
|
|
11
|
-
Set Padding 20
|
|
12
|
-
Set Framerate 24
|
|
13
|
-
Set TypingSpeed 45ms
|
|
14
|
-
|
|
15
|
-
Env PUPPETEER_SKIP_DOWNLOAD "true"
|
|
16
|
-
Env FORCE_COLOR "1"
|
|
17
|
-
Env PS1 "$ "
|
|
18
|
-
|
|
19
|
-
# ── 1. Show the test file ─────────────────────────────────────────────────────
|
|
20
|
-
Type "# 1/5 Inspect the test file"
|
|
21
|
-
Enter
|
|
22
|
-
Sleep 400ms
|
|
23
|
-
Type "cat demo/example-test.js"
|
|
24
|
-
Enter
|
|
25
|
-
Sleep 3000ms
|
|
26
|
-
|
|
27
|
-
# ── 2. Run all tests — concurrent by default, all green ──────────────────────
|
|
28
|
-
Type "# 2/5 Run tests — concurrent by default"
|
|
29
|
-
Enter
|
|
30
|
-
Sleep 400ms
|
|
31
|
-
Type "qunitx demo/example-test.js"
|
|
32
|
-
Enter
|
|
33
|
-
Sleep 7000ms
|
|
34
|
-
|
|
35
|
-
# ── 3. --debug: pipe Chrome's console.log to your terminal ───────────────────
|
|
36
|
-
Type "# 3/5 --debug: pipe Chrome console to your terminal"
|
|
37
|
-
Enter
|
|
38
|
-
Sleep 400ms
|
|
39
|
-
Type "qunitx demo/example-test.js --debug"
|
|
40
|
-
Enter
|
|
41
|
-
Sleep 7000ms
|
|
42
|
-
|
|
43
|
-
# ── 4. --failFast: stop immediately on the first failure ─────────────────────
|
|
44
|
-
Type "# 4/5 --failFast: stop on the first failure"
|
|
45
|
-
Enter
|
|
46
|
-
Sleep 400ms
|
|
47
|
-
Type "qunitx demo/failing-test.js --failFast"
|
|
48
|
-
Enter
|
|
49
|
-
Sleep 7000ms
|
|
50
|
-
|
|
51
|
-
# ── 5. --watch: stay alive and re-run on every file save ─────────────────────
|
|
52
|
-
Type "# 5/5 --watch: re-run on every file save"
|
|
53
|
-
Enter
|
|
54
|
-
Sleep 400ms
|
|
55
|
-
Type "qunitx demo/example-test.js --watch"
|
|
56
|
-
Enter
|
|
57
|
-
Sleep 6000ms
|
|
58
|
-
Ctrl+C
|
|
59
|
-
Sleep 1200ms
|
package/demo/example-test.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { module, test } from 'qunitx';
|
|
2
|
-
|
|
3
|
-
// Tests run in real headless Chrome — not jsdom, not Node.js.
|
|
4
|
-
|
|
5
|
-
module('Browser', () => {
|
|
6
|
-
test('has window, document & navigator', (assert) => {
|
|
7
|
-
assert.ok(typeof window !== 'undefined', 'window exists');
|
|
8
|
-
assert.ok(document.body !== null, 'document.body exists');
|
|
9
|
-
assert.ok(navigator.userAgent.includes('Chrome'), 'running in Chrome');
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
test('can build and query a DOM tree', (assert) => {
|
|
13
|
-
const ul = document.createElement('ul');
|
|
14
|
-
['Alice', 'Bob', 'Carol'].forEach((name) => {
|
|
15
|
-
const li = document.createElement('li');
|
|
16
|
-
li.textContent = name;
|
|
17
|
-
ul.appendChild(li);
|
|
18
|
-
});
|
|
19
|
-
assert.equal(ul.querySelectorAll('li').length, 3);
|
|
20
|
-
assert.equal(ul.querySelector('li').textContent, 'Alice');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
test('crypto.randomUUID() works', (assert) => {
|
|
24
|
-
const id = crypto.randomUUID();
|
|
25
|
-
console.log('[debug] uuid:', id);
|
|
26
|
-
assert.ok(/^[0-9a-f-]{36}$/.test(id), 'valid UUID format');
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
module('Async', () => {
|
|
31
|
-
test('resolves a promise', async (assert) => {
|
|
32
|
-
const value = await Promise.resolve('hello from Chrome');
|
|
33
|
-
assert.equal(value, 'hello from Chrome');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test('rejects are caught', async (assert) => {
|
|
37
|
-
await assert.rejects(Promise.reject(new Error('boom')), /boom/);
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
module('Assertions', () => {
|
|
42
|
-
test('equal & deepEqual', (assert) => {
|
|
43
|
-
assert.equal(1 + 1, 2);
|
|
44
|
-
assert.deepEqual(
|
|
45
|
-
{ user: 'alice', roles: ['admin', 'viewer'] },
|
|
46
|
-
{ user: 'alice', roles: ['admin', 'viewer'] },
|
|
47
|
-
);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test('throws on bad input', (assert) => {
|
|
51
|
-
assert.throws(() => JSON.parse('{bad json}'), SyntaxError);
|
|
52
|
-
});
|
|
53
|
-
});
|
package/demo/failing-test.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { module, test } from 'qunitx';
|
|
2
|
-
|
|
3
|
-
module('Cart', () => {
|
|
4
|
-
test('calculates subtotal', (assert) => {
|
|
5
|
-
const items = [{ price: 10 }, { price: 20 }, { price: 5 }];
|
|
6
|
-
const total = items.reduce((sum, item) => sum + item.price, 0);
|
|
7
|
-
assert.equal(total, 35, 'subtotal is correct');
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
test('applies 10% discount', (assert) => {
|
|
11
|
-
assert.equal(Math.round(100 * 0.9), 90);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
test('validates stock level', (assert) => {
|
|
15
|
-
const stock = 0;
|
|
16
|
-
assert.ok(stock > 0, 'expected items in stock'); // ← will fail
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
test('calculates tax', (assert) => {
|
|
20
|
-
assert.equal(100 * 0.2, 20); // ← never reached with --failFast
|
|
21
|
-
});
|
|
22
|
-
});
|
package/flake.lock
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"nodes": {
|
|
3
|
-
"flake-utils": {
|
|
4
|
-
"locked": {
|
|
5
|
-
"lastModified": 1659877975,
|
|
6
|
-
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
|
7
|
-
"owner": "numtide",
|
|
8
|
-
"repo": "flake-utils",
|
|
9
|
-
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
|
10
|
-
"type": "github"
|
|
11
|
-
},
|
|
12
|
-
"original": {
|
|
13
|
-
"owner": "numtide",
|
|
14
|
-
"repo": "flake-utils",
|
|
15
|
-
"type": "github"
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
"napalm": {
|
|
19
|
-
"inputs": {
|
|
20
|
-
"flake-utils": "flake-utils",
|
|
21
|
-
"nixpkgs": [
|
|
22
|
-
"nixpkgs"
|
|
23
|
-
]
|
|
24
|
-
},
|
|
25
|
-
"locked": {
|
|
26
|
-
"lastModified": 1672245824,
|
|
27
|
-
"narHash": "sha256-i596lbPiA/Rfx3DiJiCluxdgxWY7oGSgYMT7OmM+zik=",
|
|
28
|
-
"owner": "nix-community",
|
|
29
|
-
"repo": "napalm",
|
|
30
|
-
"rev": "7c25a05cef52dc405f4688422ce0046ca94aadcf",
|
|
31
|
-
"type": "github"
|
|
32
|
-
},
|
|
33
|
-
"original": {
|
|
34
|
-
"owner": "nix-community",
|
|
35
|
-
"repo": "napalm",
|
|
36
|
-
"type": "github"
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
"nixpkgs": {
|
|
40
|
-
"locked": {
|
|
41
|
-
"lastModified": 1772822230,
|
|
42
|
-
"narHash": "sha256-yf3iYLGbGVlIthlQIk5/4/EQDZNNEmuqKZkQssMljuw=",
|
|
43
|
-
"owner": "NixOS",
|
|
44
|
-
"repo": "nixpkgs",
|
|
45
|
-
"rev": "71caefce12ba78d84fe618cf61644dce01cf3a96",
|
|
46
|
-
"type": "github"
|
|
47
|
-
},
|
|
48
|
-
"original": {
|
|
49
|
-
"owner": "NixOS",
|
|
50
|
-
"ref": "nixos-25.11",
|
|
51
|
-
"repo": "nixpkgs",
|
|
52
|
-
"type": "github"
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
"root": {
|
|
56
|
-
"inputs": {
|
|
57
|
-
"napalm": "napalm",
|
|
58
|
-
"nixpkgs": "nixpkgs"
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
"root": "root",
|
|
63
|
-
"version": 7
|
|
64
|
-
}
|
package/flake.nix
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
description = "A flake for napalm";
|
|
3
|
-
|
|
4
|
-
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
|
|
5
|
-
inputs.napalm.url = "github:nix-community/napalm";
|
|
6
|
-
|
|
7
|
-
# NOTE: This is optional, but is how to configure napalm's env
|
|
8
|
-
inputs.napalm.inputs.nixpkgs.follows = "nixpkgs";
|
|
9
|
-
|
|
10
|
-
outputs = { self, nixpkgs, napalm }:
|
|
11
|
-
let
|
|
12
|
-
system = "x86_64-linux";
|
|
13
|
-
pkgs = nixpkgs.legacyPackages."${system}";
|
|
14
|
-
in {
|
|
15
|
-
packages."${system}".default = napalm.legacyPackages."${system}".buildPackage ./. {
|
|
16
|
-
nodejs = pkgs.nodejs_24;
|
|
17
|
-
PUPPETEER_SKIP_DOWNLOAD=1;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
devShells."${system}".default = pkgs.mkShell {
|
|
21
|
-
nativeBuildInputs = [
|
|
22
|
-
pkgs.pkg-config
|
|
23
|
-
pkgs.deno
|
|
24
|
-
pkgs.nodejs_24
|
|
25
|
-
pkgs.git-cliff
|
|
26
|
-
pkgs.vhs
|
|
27
|
-
# self.packages.default.nativeBuildInputs
|
|
28
|
-
# self.packages.default.buildInputs
|
|
29
|
-
];
|
|
30
|
-
|
|
31
|
-
doCheck = false; # Disables automatically running tests for `$ nix develop` and direnv
|
|
32
|
-
|
|
33
|
-
shellHook = ''
|
|
34
|
-
export ZDOTDIR=$(mktemp -d)
|
|
35
|
-
cat > "$ZDOTDIR/.zshrc" << 'EOF'
|
|
36
|
-
source ~/.zshrc # Source the original ~/.zshrc, required.
|
|
37
|
-
function parse_git_branch {
|
|
38
|
-
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\ ->\ \1/'
|
|
39
|
-
}
|
|
40
|
-
function display_jobs_count_if_needed {
|
|
41
|
-
local job_count=$(jobs -s | wc -l | tr -d " ")
|
|
42
|
-
if [ $job_count -gt 0 ]; then
|
|
43
|
-
echo "%B%F{yellow}%j| ";
|
|
44
|
-
fi
|
|
45
|
-
}
|
|
46
|
-
# NOTE: Custom prompt with a snowflake: signals we are in `$ nix develop` shell
|
|
47
|
-
PROMPT="%F{blue}$(date +%H:%M:%S) $(display_jobs_count_if_needed)%B%F{green}%n %F{blue}%~%F{cyan} ❄%F{yellow}$(parse_git_branch) %f%{$reset_color%}"
|
|
48
|
-
EOF
|
|
49
|
-
if [ -z "$DIRENV_IN_ENVRC" ]; then # This makes `$ nix develop` universally working with direnv without infinite loop
|
|
50
|
-
exec ${pkgs.zsh}/bin/zsh -i
|
|
51
|
-
fi
|
|
52
|
-
'';
|
|
53
|
-
};
|
|
54
|
-
};
|
|
55
|
-
}
|