Skip to content

fix(parallel): key per-test result dirs on the path, not the basename - #961

Merged
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision
Aug 1, 2026
Merged

fix(parallel): key per-test result dirs on the path, not the basename#961
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Closes#959

Under --parallel, each test file's results were bucketed into a directory named by the file's basename:

local test_suite_base="${test_file##*/}"local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"

Two files sharing a basename in different directories shared one bucket. The per-suite ordinal is unique per suite, not globally, so <tmp>/foo_test/1.result was written twice and the first write was lost. The run stayed green and simply reported fewer tests.

Same defect as #923, which fixed exactly this in build.sh: a basename isn't an identity when directories can repeat one.

📉 How it was found, and why it matters to users

Mirroring tests/unit/ onto the src/ module layout (#957/#960) produced three duplicate basenames and cost 52 tests under --parallel:

--parallel --simple --strict
with 3 duplicate basenames1536
after renaming them unique1588

A tests/ tree mirroring a src/ tree is what the docs encourage, so any user project doing it is exposed — and a failing test can vanish while CI stays green.

💡 Changes

  • The derivation folds the whole path instead of taking the basename.
  • Both sites that computed it — runner/result.sh and the pre-create in runner/exec.sh (perf(runner): stop forking per test when publishing parallel results #813) — now call one shared helper, so they cannot drift apart.
  • It stays pure parameter expansion: this runs once per test in every parallel worker and the path must remain fork-free. The fork-budget acceptance tests pass unchanged (11/11).

Nothing parses the directory name — aggregate_parallel_results globs whatever subdirectories exist — so the rename is invisible downstream.

✅ Verification

TDD: the new acceptance test in bashunit_parallel_consistency_test.sh runs two same-named fixture files from different directories in both modes and compares counts. Verified red without the fix (sequential 2, parallel 1) and green with it.

It asserts on extracted counts rather than the rendered summary — the parallel spinner leaves control bytes on that line — plus a guard so both sides can't collapse to empty and match vacuously.

Green: sequential (1630) · --parallel --simple --strict (1589) · fork budget · make sa · make lint · bash build.sh bin -v✅ Build verified ✅. CHANGELOG updated under Fixed.

Under --parallel, each test file's results were bucketed into a directory named
by the file's basename:
local test_suite_base="${test_file##*/}"
local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"
Two files sharing a basename in different directories therefore shared one
bucket, and the per-suite ordinal is unique per suite rather than globally, so
`<tmp>/foo_test/1.result` was written twice and the first write was lost. The
run stayed green and simply reported fewer tests.
Same defect as #923, which fixed exactly this in build.sh: a basename is not an
identity when directories can repeat one.
Found while mirroring tests/unit onto the src/ module layout (#957/#960), which
produced three duplicate basenames and cost 52 tests under --parallel. That
layout is what the docs encourage, so any user project doing it is exposed.
The derivation now folds the whole path, and both sites that computed it --
runner/result.sh and the pre-create in runner/exec.sh (#813) -- call one shared
helper, so they cannot drift apart. It stays pure parameter expansion: this runs
once per test in every parallel worker and the path must remain fork-free. The
fork-budget acceptance tests pass unchanged.
Nothing parses the directory name; aggregate_parallel_results globs whatever
subdirectories exist.
Closes#959
@ChemaclassChemaclass added the bug Something isn't working label Aug 1, 2026
@ChemaclassChemaclass self-assigned this Aug 1, 2026
@Chemaclass
Chemaclass merged commit 0608298 into mainAug 1, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the fix/959-parallel-basename-collision branch August 1, 2026 21:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(parallel): same-named test files in different directories silently lose results

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix(parallel): key per-test result dirs on the path, not the basename by Chemaclass · Pull Request #961 · TypedDevs/bashunit · GitHub
Skip to content

fix(parallel): key per-test result dirs on the path, not the basename - #961

Merged
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision
Aug 1, 2026
Merged

fix(parallel): key per-test result dirs on the path, not the basename#961
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Closes#959

Under --parallel, each test file's results were bucketed into a directory named by the file's basename:

local test_suite_base="${test_file##*/}"local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"

Two files sharing a basename in different directories shared one bucket. The per-suite ordinal is unique per suite, not globally, so <tmp>/foo_test/1.result was written twice and the first write was lost. The run stayed green and simply reported fewer tests.

Same defect as #923, which fixed exactly this in build.sh: a basename isn't an identity when directories can repeat one.

📉 How it was found, and why it matters to users

Mirroring tests/unit/ onto the src/ module layout (#957/#960) produced three duplicate basenames and cost 52 tests under --parallel:

--parallel --simple --strict
with 3 duplicate basenames1536
after renaming them unique1588

A tests/ tree mirroring a src/ tree is what the docs encourage, so any user project doing it is exposed — and a failing test can vanish while CI stays green.

💡 Changes

  • The derivation folds the whole path instead of taking the basename.
  • Both sites that computed it — runner/result.sh and the pre-create in runner/exec.sh (perf(runner): stop forking per test when publishing parallel results #813) — now call one shared helper, so they cannot drift apart.
  • It stays pure parameter expansion: this runs once per test in every parallel worker and the path must remain fork-free. The fork-budget acceptance tests pass unchanged (11/11).

Nothing parses the directory name — aggregate_parallel_results globs whatever subdirectories exist — so the rename is invisible downstream.

✅ Verification

TDD: the new acceptance test in bashunit_parallel_consistency_test.sh runs two same-named fixture files from different directories in both modes and compares counts. Verified red without the fix (sequential 2, parallel 1) and green with it.

It asserts on extracted counts rather than the rendered summary — the parallel spinner leaves control bytes on that line — plus a guard so both sides can't collapse to empty and match vacuously.

Green: sequential (1630) · --parallel --simple --strict (1589) · fork budget · make sa · make lint · bash build.sh bin -v✅ Build verified ✅. CHANGELOG updated under Fixed.

Under --parallel, each test file's results were bucketed into a directory named
by the file's basename:
local test_suite_base="${test_file##*/}"
local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"
Two files sharing a basename in different directories therefore shared one
bucket, and the per-suite ordinal is unique per suite rather than globally, so
`<tmp>/foo_test/1.result` was written twice and the first write was lost. The
run stayed green and simply reported fewer tests.
Same defect as #923, which fixed exactly this in build.sh: a basename is not an
identity when directories can repeat one.
Found while mirroring tests/unit onto the src/ module layout (#957/#960), which
produced three duplicate basenames and cost 52 tests under --parallel. That
layout is what the docs encourage, so any user project doing it is exposed.
The derivation now folds the whole path, and both sites that computed it --
runner/result.sh and the pre-create in runner/exec.sh (#813) -- call one shared
helper, so they cannot drift apart. It stays pure parameter expansion: this runs
once per test in every parallel worker and the path must remain fork-free. The
fork-budget acceptance tests pass unchanged.
Nothing parses the directory name; aggregate_parallel_results globs whatever
subdirectories exist.
Closes#959
@ChemaclassChemaclass added the bug Something isn't working label Aug 1, 2026
@ChemaclassChemaclass self-assigned this Aug 1, 2026
@Chemaclass
Chemaclass merged commit 0608298 into mainAug 1, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the fix/959-parallel-basename-collision branch August 1, 2026 21:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(parallel): same-named test files in different directories silently lose results

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(parallel): key per-test result dirs on the path, not the basename by Chemaclass · Pull Request #961 · TypedDevs/bashunit · GitHub
Skip to content

fix(parallel): key per-test result dirs on the path, not the basename - #961

Merged
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision
Aug 1, 2026
Merged

fix(parallel): key per-test result dirs on the path, not the basename#961
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Closes#959

Under --parallel, each test file's results were bucketed into a directory named by the file's basename:

local test_suite_base="${test_file##*/}"local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"

Two files sharing a basename in different directories shared one bucket. The per-suite ordinal is unique per suite, not globally, so <tmp>/foo_test/1.result was written twice and the first write was lost. The run stayed green and simply reported fewer tests.

Same defect as #923, which fixed exactly this in build.sh: a basename isn't an identity when directories can repeat one.

📉 How it was found, and why it matters to users

Mirroring tests/unit/ onto the src/ module layout (#957/#960) produced three duplicate basenames and cost 52 tests under --parallel:

--parallel --simple --strict
with 3 duplicate basenames1536
after renaming them unique1588

A tests/ tree mirroring a src/ tree is what the docs encourage, so any user project doing it is exposed — and a failing test can vanish while CI stays green.

💡 Changes

  • The derivation folds the whole path instead of taking the basename.
  • Both sites that computed it — runner/result.sh and the pre-create in runner/exec.sh (perf(runner): stop forking per test when publishing parallel results #813) — now call one shared helper, so they cannot drift apart.
  • It stays pure parameter expansion: this runs once per test in every parallel worker and the path must remain fork-free. The fork-budget acceptance tests pass unchanged (11/11).

Nothing parses the directory name — aggregate_parallel_results globs whatever subdirectories exist — so the rename is invisible downstream.

✅ Verification

TDD: the new acceptance test in bashunit_parallel_consistency_test.sh runs two same-named fixture files from different directories in both modes and compares counts. Verified red without the fix (sequential 2, parallel 1) and green with it.

It asserts on extracted counts rather than the rendered summary — the parallel spinner leaves control bytes on that line — plus a guard so both sides can't collapse to empty and match vacuously.

Green: sequential (1630) · --parallel --simple --strict (1589) · fork budget · make sa · make lint · bash build.sh bin -v✅ Build verified ✅. CHANGELOG updated under Fixed.

Under --parallel, each test file's results were bucketed into a directory named
by the file's basename:
local test_suite_base="${test_file##*/}"
local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"
Two files sharing a basename in different directories therefore shared one
bucket, and the per-suite ordinal is unique per suite rather than globally, so
`<tmp>/foo_test/1.result` was written twice and the first write was lost. The
run stayed green and simply reported fewer tests.
Same defect as #923, which fixed exactly this in build.sh: a basename is not an
identity when directories can repeat one.
Found while mirroring tests/unit onto the src/ module layout (#957/#960), which
produced three duplicate basenames and cost 52 tests under --parallel. That
layout is what the docs encourage, so any user project doing it is exposed.
The derivation now folds the whole path, and both sites that computed it --
runner/result.sh and the pre-create in runner/exec.sh (#813) -- call one shared
helper, so they cannot drift apart. It stays pure parameter expansion: this runs
once per test in every parallel worker and the path must remain fork-free. The
fork-budget acceptance tests pass unchanged.
Nothing parses the directory name; aggregate_parallel_results globs whatever
subdirectories exist.
Closes#959
@ChemaclassChemaclass added the bug Something isn't working label Aug 1, 2026
@ChemaclassChemaclass self-assigned this Aug 1, 2026
@Chemaclass
Chemaclass merged commit 0608298 into mainAug 1, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the fix/959-parallel-basename-collision branch August 1, 2026 21:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(parallel): same-named test files in different directories silently lose results

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(parallel): key per-test result dirs on the path, not the basename by Chemaclass · Pull Request #961 · TypedDevs/bashunit · GitHub
Skip to content

fix(parallel): key per-test result dirs on the path, not the basename - #961

Merged
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision
Aug 1, 2026
Merged

fix(parallel): key per-test result dirs on the path, not the basename#961
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Closes#959

Under --parallel, each test file's results were bucketed into a directory named by the file's basename:

local test_suite_base="${test_file##*/}"local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"

Two files sharing a basename in different directories shared one bucket. The per-suite ordinal is unique per suite, not globally, so <tmp>/foo_test/1.result was written twice and the first write was lost. The run stayed green and simply reported fewer tests.

Same defect as #923, which fixed exactly this in build.sh: a basename isn't an identity when directories can repeat one.

📉 How it was found, and why it matters to users

Mirroring tests/unit/ onto the src/ module layout (#957/#960) produced three duplicate basenames and cost 52 tests under --parallel:

--parallel --simple --strict
with 3 duplicate basenames1536
after renaming them unique1588

A tests/ tree mirroring a src/ tree is what the docs encourage, so any user project doing it is exposed — and a failing test can vanish while CI stays green.

💡 Changes

  • The derivation folds the whole path instead of taking the basename.
  • Both sites that computed it — runner/result.sh and the pre-create in runner/exec.sh (perf(runner): stop forking per test when publishing parallel results #813) — now call one shared helper, so they cannot drift apart.
  • It stays pure parameter expansion: this runs once per test in every parallel worker and the path must remain fork-free. The fork-budget acceptance tests pass unchanged (11/11).

Nothing parses the directory name — aggregate_parallel_results globs whatever subdirectories exist — so the rename is invisible downstream.

✅ Verification

TDD: the new acceptance test in bashunit_parallel_consistency_test.sh runs two same-named fixture files from different directories in both modes and compares counts. Verified red without the fix (sequential 2, parallel 1) and green with it.

It asserts on extracted counts rather than the rendered summary — the parallel spinner leaves control bytes on that line — plus a guard so both sides can't collapse to empty and match vacuously.

Green: sequential (1630) · --parallel --simple --strict (1589) · fork budget · make sa · make lint · bash build.sh bin -v✅ Build verified ✅. CHANGELOG updated under Fixed.

Under --parallel, each test file's results were bucketed into a directory named
by the file's basename:
local test_suite_base="${test_file##*/}"
local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"
Two files sharing a basename in different directories therefore shared one
bucket, and the per-suite ordinal is unique per suite rather than globally, so
`<tmp>/foo_test/1.result` was written twice and the first write was lost. The
run stayed green and simply reported fewer tests.
Same defect as #923, which fixed exactly this in build.sh: a basename is not an
identity when directories can repeat one.
Found while mirroring tests/unit onto the src/ module layout (#957/#960), which
produced three duplicate basenames and cost 52 tests under --parallel. That
layout is what the docs encourage, so any user project doing it is exposed.
The derivation now folds the whole path, and both sites that computed it --
runner/result.sh and the pre-create in runner/exec.sh (#813) -- call one shared
helper, so they cannot drift apart. It stays pure parameter expansion: this runs
once per test in every parallel worker and the path must remain fork-free. The
fork-budget acceptance tests pass unchanged.
Nothing parses the directory name; aggregate_parallel_results globs whatever
subdirectories exist.
Closes#959
@ChemaclassChemaclass added the bug Something isn't working label Aug 1, 2026
@ChemaclassChemaclass self-assigned this Aug 1, 2026
@Chemaclass
Chemaclass merged commit 0608298 into mainAug 1, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the fix/959-parallel-basename-collision branch August 1, 2026 21:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(parallel): same-named test files in different directories silently lose results

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix(parallel): key per-test result dirs on the path, not the basename by Chemaclass · Pull Request #961 · TypedDevs/bashunit · GitHub
Skip to content

fix(parallel): key per-test result dirs on the path, not the basename - #961

Merged
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision
Aug 1, 2026
Merged

fix(parallel): key per-test result dirs on the path, not the basename#961
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Closes#959

Under --parallel, each test file's results were bucketed into a directory named by the file's basename:

local test_suite_base="${test_file##*/}"local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"

Two files sharing a basename in different directories shared one bucket. The per-suite ordinal is unique per suite, not globally, so <tmp>/foo_test/1.result was written twice and the first write was lost. The run stayed green and simply reported fewer tests.

Same defect as #923, which fixed exactly this in build.sh: a basename isn't an identity when directories can repeat one.

📉 How it was found, and why it matters to users

Mirroring tests/unit/ onto the src/ module layout (#957/#960) produced three duplicate basenames and cost 52 tests under --parallel:

--parallel --simple --strict
with 3 duplicate basenames1536
after renaming them unique1588

A tests/ tree mirroring a src/ tree is what the docs encourage, so any user project doing it is exposed — and a failing test can vanish while CI stays green.

💡 Changes

  • The derivation folds the whole path instead of taking the basename.
  • Both sites that computed it — runner/result.sh and the pre-create in runner/exec.sh (perf(runner): stop forking per test when publishing parallel results #813) — now call one shared helper, so they cannot drift apart.
  • It stays pure parameter expansion: this runs once per test in every parallel worker and the path must remain fork-free. The fork-budget acceptance tests pass unchanged (11/11).

Nothing parses the directory name — aggregate_parallel_results globs whatever subdirectories exist — so the rename is invisible downstream.

✅ Verification

TDD: the new acceptance test in bashunit_parallel_consistency_test.sh runs two same-named fixture files from different directories in both modes and compares counts. Verified red without the fix (sequential 2, parallel 1) and green with it.

It asserts on extracted counts rather than the rendered summary — the parallel spinner leaves control bytes on that line — plus a guard so both sides can't collapse to empty and match vacuously.

Green: sequential (1630) · --parallel --simple --strict (1589) · fork budget · make sa · make lint · bash build.sh bin -v✅ Build verified ✅. CHANGELOG updated under Fixed.

Under --parallel, each test file's results were bucketed into a directory named
by the file's basename:
local test_suite_base="${test_file##*/}"
local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"
Two files sharing a basename in different directories therefore shared one
bucket, and the per-suite ordinal is unique per suite rather than globally, so
`<tmp>/foo_test/1.result` was written twice and the first write was lost. The
run stayed green and simply reported fewer tests.
Same defect as #923, which fixed exactly this in build.sh: a basename is not an
identity when directories can repeat one.
Found while mirroring tests/unit onto the src/ module layout (#957/#960), which
produced three duplicate basenames and cost 52 tests under --parallel. That
layout is what the docs encourage, so any user project doing it is exposed.
The derivation now folds the whole path, and both sites that computed it --
runner/result.sh and the pre-create in runner/exec.sh (#813) -- call one shared
helper, so they cannot drift apart. It stays pure parameter expansion: this runs
once per test in every parallel worker and the path must remain fork-free. The
fork-budget acceptance tests pass unchanged.
Nothing parses the directory name; aggregate_parallel_results globs whatever
subdirectories exist.
Closes#959
@ChemaclassChemaclass added the bug Something isn't working label Aug 1, 2026
@ChemaclassChemaclass self-assigned this Aug 1, 2026
@Chemaclass
Chemaclass merged commit 0608298 into mainAug 1, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the fix/959-parallel-basename-collision branch August 1, 2026 21:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(parallel): same-named test files in different directories silently lose results

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(parallel): key per-test result dirs on the path, not the basename by Chemaclass · Pull Request #961 · TypedDevs/bashunit · GitHub
Skip to content

fix(parallel): key per-test result dirs on the path, not the basename - #961

Merged
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision
Aug 1, 2026
Merged

fix(parallel): key per-test result dirs on the path, not the basename#961
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Closes#959

Under --parallel, each test file's results were bucketed into a directory named by the file's basename:

local test_suite_base="${test_file##*/}"local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"

Two files sharing a basename in different directories shared one bucket. The per-suite ordinal is unique per suite, not globally, so <tmp>/foo_test/1.result was written twice and the first write was lost. The run stayed green and simply reported fewer tests.

Same defect as #923, which fixed exactly this in build.sh: a basename isn't an identity when directories can repeat one.

📉 How it was found, and why it matters to users

Mirroring tests/unit/ onto the src/ module layout (#957/#960) produced three duplicate basenames and cost 52 tests under --parallel:

--parallel --simple --strict
with 3 duplicate basenames1536
after renaming them unique1588

A tests/ tree mirroring a src/ tree is what the docs encourage, so any user project doing it is exposed — and a failing test can vanish while CI stays green.

💡 Changes

  • The derivation folds the whole path instead of taking the basename.
  • Both sites that computed it — runner/result.sh and the pre-create in runner/exec.sh (perf(runner): stop forking per test when publishing parallel results #813) — now call one shared helper, so they cannot drift apart.
  • It stays pure parameter expansion: this runs once per test in every parallel worker and the path must remain fork-free. The fork-budget acceptance tests pass unchanged (11/11).

Nothing parses the directory name — aggregate_parallel_results globs whatever subdirectories exist — so the rename is invisible downstream.

✅ Verification

TDD: the new acceptance test in bashunit_parallel_consistency_test.sh runs two same-named fixture files from different directories in both modes and compares counts. Verified red without the fix (sequential 2, parallel 1) and green with it.

It asserts on extracted counts rather than the rendered summary — the parallel spinner leaves control bytes on that line — plus a guard so both sides can't collapse to empty and match vacuously.

Green: sequential (1630) · --parallel --simple --strict (1589) · fork budget · make sa · make lint · bash build.sh bin -v✅ Build verified ✅. CHANGELOG updated under Fixed.

Under --parallel, each test file's results were bucketed into a directory named
by the file's basename:
local test_suite_base="${test_file##*/}"
local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"
Two files sharing a basename in different directories therefore shared one
bucket, and the per-suite ordinal is unique per suite rather than globally, so
`<tmp>/foo_test/1.result` was written twice and the first write was lost. The
run stayed green and simply reported fewer tests.
Same defect as #923, which fixed exactly this in build.sh: a basename is not an
identity when directories can repeat one.
Found while mirroring tests/unit onto the src/ module layout (#957/#960), which
produced three duplicate basenames and cost 52 tests under --parallel. That
layout is what the docs encourage, so any user project doing it is exposed.
The derivation now folds the whole path, and both sites that computed it --
runner/result.sh and the pre-create in runner/exec.sh (#813) -- call one shared
helper, so they cannot drift apart. It stays pure parameter expansion: this runs
once per test in every parallel worker and the path must remain fork-free. The
fork-budget acceptance tests pass unchanged.
Nothing parses the directory name; aggregate_parallel_results globs whatever
subdirectories exist.
Closes#959
@ChemaclassChemaclass added the bug Something isn't working label Aug 1, 2026
@ChemaclassChemaclass self-assigned this Aug 1, 2026
@Chemaclass
Chemaclass merged commit 0608298 into mainAug 1, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the fix/959-parallel-basename-collision branch August 1, 2026 21:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(parallel): same-named test files in different directories silently lose results

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(parallel): key per-test result dirs on the path, not the basename by Chemaclass · Pull Request #961 · TypedDevs/bashunit · GitHub
Skip to content

fix(parallel): key per-test result dirs on the path, not the basename - #961

Merged
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision
Aug 1, 2026
Merged

fix(parallel): key per-test result dirs on the path, not the basename#961
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Closes#959

Under --parallel, each test file's results were bucketed into a directory named by the file's basename:

local test_suite_base="${test_file##*/}"local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"

Two files sharing a basename in different directories shared one bucket. The per-suite ordinal is unique per suite, not globally, so <tmp>/foo_test/1.result was written twice and the first write was lost. The run stayed green and simply reported fewer tests.

Same defect as #923, which fixed exactly this in build.sh: a basename isn't an identity when directories can repeat one.

📉 How it was found, and why it matters to users

Mirroring tests/unit/ onto the src/ module layout (#957/#960) produced three duplicate basenames and cost 52 tests under --parallel:

--parallel --simple --strict
with 3 duplicate basenames1536
after renaming them unique1588

A tests/ tree mirroring a src/ tree is what the docs encourage, so any user project doing it is exposed — and a failing test can vanish while CI stays green.

💡 Changes

  • The derivation folds the whole path instead of taking the basename.
  • Both sites that computed it — runner/result.sh and the pre-create in runner/exec.sh (perf(runner): stop forking per test when publishing parallel results #813) — now call one shared helper, so they cannot drift apart.
  • It stays pure parameter expansion: this runs once per test in every parallel worker and the path must remain fork-free. The fork-budget acceptance tests pass unchanged (11/11).

Nothing parses the directory name — aggregate_parallel_results globs whatever subdirectories exist — so the rename is invisible downstream.

✅ Verification

TDD: the new acceptance test in bashunit_parallel_consistency_test.sh runs two same-named fixture files from different directories in both modes and compares counts. Verified red without the fix (sequential 2, parallel 1) and green with it.

It asserts on extracted counts rather than the rendered summary — the parallel spinner leaves control bytes on that line — plus a guard so both sides can't collapse to empty and match vacuously.

Green: sequential (1630) · --parallel --simple --strict (1589) · fork budget · make sa · make lint · bash build.sh bin -v✅ Build verified ✅. CHANGELOG updated under Fixed.

Under --parallel, each test file's results were bucketed into a directory named
by the file's basename:
local test_suite_base="${test_file##*/}"
local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"
Two files sharing a basename in different directories therefore shared one
bucket, and the per-suite ordinal is unique per suite rather than globally, so
`<tmp>/foo_test/1.result` was written twice and the first write was lost. The
run stayed green and simply reported fewer tests.
Same defect as #923, which fixed exactly this in build.sh: a basename is not an
identity when directories can repeat one.
Found while mirroring tests/unit onto the src/ module layout (#957/#960), which
produced three duplicate basenames and cost 52 tests under --parallel. That
layout is what the docs encourage, so any user project doing it is exposed.
The derivation now folds the whole path, and both sites that computed it --
runner/result.sh and the pre-create in runner/exec.sh (#813) -- call one shared
helper, so they cannot drift apart. It stays pure parameter expansion: this runs
once per test in every parallel worker and the path must remain fork-free. The
fork-budget acceptance tests pass unchanged.
Nothing parses the directory name; aggregate_parallel_results globs whatever
subdirectories exist.
Closes#959
@ChemaclassChemaclass added the bug Something isn't working label Aug 1, 2026
@ChemaclassChemaclass self-assigned this Aug 1, 2026
@Chemaclass
Chemaclass merged commit 0608298 into mainAug 1, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the fix/959-parallel-basename-collision branch August 1, 2026 21:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(parallel): same-named test files in different directories silently lose results

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); fix(parallel): key per-test result dirs on the path, not the basename by Chemaclass · Pull Request #961 · TypedDevs/bashunit · GitHub
Skip to content

fix(parallel): key per-test result dirs on the path, not the basename - #961

Merged
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision
Aug 1, 2026
Merged

fix(parallel): key per-test result dirs on the path, not the basename#961
Chemaclass merged 1 commit into
mainfrom
fix/959-parallel-basename-collision

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Closes#959

Under --parallel, each test file's results were bucketed into a directory named by the file's basename:

local test_suite_base="${test_file##*/}"local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"

Two files sharing a basename in different directories shared one bucket. The per-suite ordinal is unique per suite, not globally, so <tmp>/foo_test/1.result was written twice and the first write was lost. The run stayed green and simply reported fewer tests.

Same defect as #923, which fixed exactly this in build.sh: a basename isn't an identity when directories can repeat one.

📉 How it was found, and why it matters to users

Mirroring tests/unit/ onto the src/ module layout (#957/#960) produced three duplicate basenames and cost 52 tests under --parallel:

--parallel --simple --strict
with 3 duplicate basenames1536
after renaming them unique1588

A tests/ tree mirroring a src/ tree is what the docs encourage, so any user project doing it is exposed — and a failing test can vanish while CI stays green.

💡 Changes

  • The derivation folds the whole path instead of taking the basename.
  • Both sites that computed it — runner/result.sh and the pre-create in runner/exec.sh (perf(runner): stop forking per test when publishing parallel results #813) — now call one shared helper, so they cannot drift apart.
  • It stays pure parameter expansion: this runs once per test in every parallel worker and the path must remain fork-free. The fork-budget acceptance tests pass unchanged (11/11).

Nothing parses the directory name — aggregate_parallel_results globs whatever subdirectories exist — so the rename is invisible downstream.

✅ Verification

TDD: the new acceptance test in bashunit_parallel_consistency_test.sh runs two same-named fixture files from different directories in both modes and compares counts. Verified red without the fix (sequential 2, parallel 1) and green with it.

It asserts on extracted counts rather than the rendered summary — the parallel spinner leaves control bytes on that line — plus a guard so both sides can't collapse to empty and match vacuously.

Green: sequential (1630) · --parallel --simple --strict (1589) · fork budget · make sa · make lint · bash build.sh bin -v✅ Build verified ✅. CHANGELOG updated under Fixed.

Under --parallel, each test file's results were bucketed into a directory named
by the file's basename:
local test_suite_base="${test_file##*/}"
local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/${test_suite_base%.sh}"
Two files sharing a basename in different directories therefore shared one
bucket, and the per-suite ordinal is unique per suite rather than globally, so
`<tmp>/foo_test/1.result` was written twice and the first write was lost. The
run stayed green and simply reported fewer tests.
Same defect as #923, which fixed exactly this in build.sh: a basename is not an
identity when directories can repeat one.
Found while mirroring tests/unit onto the src/ module layout (#957/#960), which
produced three duplicate basenames and cost 52 tests under --parallel. That
layout is what the docs encourage, so any user project doing it is exposed.
The derivation now folds the whole path, and both sites that computed it --
runner/result.sh and the pre-create in runner/exec.sh (#813) -- call one shared
helper, so they cannot drift apart. It stays pure parameter expansion: this runs
once per test in every parallel worker and the path must remain fork-free. The
fork-budget acceptance tests pass unchanged.
Nothing parses the directory name; aggregate_parallel_results globs whatever
subdirectories exist.
Closes#959
@ChemaclassChemaclass added the bug Something isn't working label Aug 1, 2026
@ChemaclassChemaclass self-assigned this Aug 1, 2026
@Chemaclass
Chemaclass merged commit 0608298 into mainAug 1, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the fix/959-parallel-basename-collision branch August 1, 2026 21:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(parallel): same-named test files in different directories silently lose results

1 participant

@Chemaclass