Skip to content

feat(assert): a composed assertion should count and report once - #921

Merged
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once
Jul 29, 2026
Merged

feat(assert): a composed assertion should count and report once#921
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #917

A custom assertion composed from built-in ones counts one assertion per inner step, and its failure names that step rather than the check the test author wrote — assert_http_success reported 2 assertions per call and failed with Expected '500' to be less than '300'.

The issue proposed an implicit nesting-depth counter. Verified on main, that does not work: the inner assertions are siblings, not nested — the first has already returned when the second starts, so both read depth 0. Detecting the enclosing assert_* frame instead would classify the inner assertion of assert_assertion_fails (#916) as nested and silence the counters its verdict detection reads, and would shift the totals of every suite already composing assertions. So this ships as an opt-in marker.

💡 Changes

  • Add bashunit::assert_once <label> <actual>: declared at the top of a custom assertion, it absorbs everything asserted inside into one reported assertion, labelled with the calling test.
  • Opt-in, so no existing totals change, assert_assertion_* keeps working, and repeated calls from a loop still count once each.
  • Bash has no cheap return hook, so the marker counts optimistically and the flush converts to a failure — totals stay correct at every point without observing the frame return.
  • Absorption hooks sit behind a plain global test in the four reporting choke points, keeping the per-assertion path flat.

… once
A custom assertion built out of built-in assertions counts one assertion per
inner step, and its failure names that step rather than the check the test
author wrote. `assert_http_success` composed from two comparisons reported 2
assertions per call and failed with "Expected '500' to be less than '300'".
Add an opt-in marker: `bashunit::assert_once <label> <actual>` at the top of a
custom assertion absorbs everything it asserts into a single reported
assertion, labelled with the test that called it.
The issue proposed an implicit nesting-depth counter. That does not work here:
the inner assertions are siblings, not nested frames -- the first has already
returned when the second starts, so both read depth 0. What distinguishes
composed from direct is an enclosing assert_* frame, and detecting that
implicitly would classify the inner assertion of assert_assertion_fails (#916)
as nested, silencing the very counters its verdict detection reads. An implicit
rule would also shift the totals of every suite already composing assertions.
Bash gives no cheap hook on a user function's return, so the marker counts one
passing assertion immediately and the flush converts it to a failure if
anything it absorbed failed. Totals are therefore correct at every point in
time without ever observing the declaring frame return. The marker is settled
by the next assert_once call (which is what makes a loop count once per
iteration), by an assertion reached after the declaring frame returned, or by
the end of the test.
The end-of-test flush runs from the EXIT trap, where the test frame is gone, so
the label is resolved eagerly at declaration time; otherwise failures were
reported as "Bashunit::assert::once flush".
Absorption hooks live in state::add_assertions_passed, assert::mark_failed,
console_results::print_failed_test and ::print_failure_message, each behind a
plain global test so the per-assertion path stays flat. assert::_capture saves
and restores the whole marker so #916 keeps working around it.
Closes#917
@ChemaclassChemaclass added the enhancement New feature or request label Jul 29, 2026
@ChemaclassChemaclass self-assigned this Jul 29, 2026
@Chemaclass
Chemaclass merged commit 96f25c3 into mainJul 29, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/917-composed-assertion-counts-once branch July 29, 2026 05:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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" + '
feat(assert): a composed assertion should count and report once by Chemaclass · Pull Request #921 · TypedDevs/bashunit · GitHub
Skip to content

feat(assert): a composed assertion should count and report once - #921

Merged
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once
Jul 29, 2026
Merged

feat(assert): a composed assertion should count and report once#921
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #917

A custom assertion composed from built-in ones counts one assertion per inner step, and its failure names that step rather than the check the test author wrote — assert_http_success reported 2 assertions per call and failed with Expected '500' to be less than '300'.

The issue proposed an implicit nesting-depth counter. Verified on main, that does not work: the inner assertions are siblings, not nested — the first has already returned when the second starts, so both read depth 0. Detecting the enclosing assert_* frame instead would classify the inner assertion of assert_assertion_fails (#916) as nested and silence the counters its verdict detection reads, and would shift the totals of every suite already composing assertions. So this ships as an opt-in marker.

💡 Changes

  • Add bashunit::assert_once <label> <actual>: declared at the top of a custom assertion, it absorbs everything asserted inside into one reported assertion, labelled with the calling test.
  • Opt-in, so no existing totals change, assert_assertion_* keeps working, and repeated calls from a loop still count once each.
  • Bash has no cheap return hook, so the marker counts optimistically and the flush converts to a failure — totals stay correct at every point without observing the frame return.
  • Absorption hooks sit behind a plain global test in the four reporting choke points, keeping the per-assertion path flat.

… once
A custom assertion built out of built-in assertions counts one assertion per
inner step, and its failure names that step rather than the check the test
author wrote. `assert_http_success` composed from two comparisons reported 2
assertions per call and failed with "Expected '500' to be less than '300'".
Add an opt-in marker: `bashunit::assert_once <label> <actual>` at the top of a
custom assertion absorbs everything it asserts into a single reported
assertion, labelled with the test that called it.
The issue proposed an implicit nesting-depth counter. That does not work here:
the inner assertions are siblings, not nested frames -- the first has already
returned when the second starts, so both read depth 0. What distinguishes
composed from direct is an enclosing assert_* frame, and detecting that
implicitly would classify the inner assertion of assert_assertion_fails (#916)
as nested, silencing the very counters its verdict detection reads. An implicit
rule would also shift the totals of every suite already composing assertions.
Bash gives no cheap hook on a user function's return, so the marker counts one
passing assertion immediately and the flush converts it to a failure if
anything it absorbed failed. Totals are therefore correct at every point in
time without ever observing the declaring frame return. The marker is settled
by the next assert_once call (which is what makes a loop count once per
iteration), by an assertion reached after the declaring frame returned, or by
the end of the test.
The end-of-test flush runs from the EXIT trap, where the test frame is gone, so
the label is resolved eagerly at declaration time; otherwise failures were
reported as "Bashunit::assert::once flush".
Absorption hooks live in state::add_assertions_passed, assert::mark_failed,
console_results::print_failed_test and ::print_failure_message, each behind a
plain global test so the per-assertion path stays flat. assert::_capture saves
and restores the whole marker so #916 keeps working around it.
Closes#917
@ChemaclassChemaclass added the enhancement New feature or request label Jul 29, 2026
@ChemaclassChemaclass self-assigned this Jul 29, 2026
@Chemaclass
Chemaclass merged commit 96f25c3 into mainJul 29, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/917-composed-assertion-counts-once branch July 29, 2026 05:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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('^' + ".*" + ' feat(assert): a composed assertion should count and report once by Chemaclass · Pull Request #921 · TypedDevs/bashunit · GitHub
Skip to content

feat(assert): a composed assertion should count and report once - #921

Merged
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once
Jul 29, 2026
Merged

feat(assert): a composed assertion should count and report once#921
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #917

A custom assertion composed from built-in ones counts one assertion per inner step, and its failure names that step rather than the check the test author wrote — assert_http_success reported 2 assertions per call and failed with Expected '500' to be less than '300'.

The issue proposed an implicit nesting-depth counter. Verified on main, that does not work: the inner assertions are siblings, not nested — the first has already returned when the second starts, so both read depth 0. Detecting the enclosing assert_* frame instead would classify the inner assertion of assert_assertion_fails (#916) as nested and silence the counters its verdict detection reads, and would shift the totals of every suite already composing assertions. So this ships as an opt-in marker.

💡 Changes

  • Add bashunit::assert_once <label> <actual>: declared at the top of a custom assertion, it absorbs everything asserted inside into one reported assertion, labelled with the calling test.
  • Opt-in, so no existing totals change, assert_assertion_* keeps working, and repeated calls from a loop still count once each.
  • Bash has no cheap return hook, so the marker counts optimistically and the flush converts to a failure — totals stay correct at every point without observing the frame return.
  • Absorption hooks sit behind a plain global test in the four reporting choke points, keeping the per-assertion path flat.

… once
A custom assertion built out of built-in assertions counts one assertion per
inner step, and its failure names that step rather than the check the test
author wrote. `assert_http_success` composed from two comparisons reported 2
assertions per call and failed with "Expected '500' to be less than '300'".
Add an opt-in marker: `bashunit::assert_once <label> <actual>` at the top of a
custom assertion absorbs everything it asserts into a single reported
assertion, labelled with the test that called it.
The issue proposed an implicit nesting-depth counter. That does not work here:
the inner assertions are siblings, not nested frames -- the first has already
returned when the second starts, so both read depth 0. What distinguishes
composed from direct is an enclosing assert_* frame, and detecting that
implicitly would classify the inner assertion of assert_assertion_fails (#916)
as nested, silencing the very counters its verdict detection reads. An implicit
rule would also shift the totals of every suite already composing assertions.
Bash gives no cheap hook on a user function's return, so the marker counts one
passing assertion immediately and the flush converts it to a failure if
anything it absorbed failed. Totals are therefore correct at every point in
time without ever observing the declaring frame return. The marker is settled
by the next assert_once call (which is what makes a loop count once per
iteration), by an assertion reached after the declaring frame returned, or by
the end of the test.
The end-of-test flush runs from the EXIT trap, where the test frame is gone, so
the label is resolved eagerly at declaration time; otherwise failures were
reported as "Bashunit::assert::once flush".
Absorption hooks live in state::add_assertions_passed, assert::mark_failed,
console_results::print_failed_test and ::print_failure_message, each behind a
plain global test so the per-assertion path stays flat. assert::_capture saves
and restores the whole marker so #916 keeps working around it.
Closes#917
@ChemaclassChemaclass added the enhancement New feature or request label Jul 29, 2026
@ChemaclassChemaclass self-assigned this Jul 29, 2026
@Chemaclass
Chemaclass merged commit 96f25c3 into mainJul 29, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/917-composed-assertion-counts-once branch July 29, 2026 05:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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('^' + ".*" + ' feat(assert): a composed assertion should count and report once by Chemaclass · Pull Request #921 · TypedDevs/bashunit · GitHub
Skip to content

feat(assert): a composed assertion should count and report once - #921

Merged
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once
Jul 29, 2026
Merged

feat(assert): a composed assertion should count and report once#921
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #917

A custom assertion composed from built-in ones counts one assertion per inner step, and its failure names that step rather than the check the test author wrote — assert_http_success reported 2 assertions per call and failed with Expected '500' to be less than '300'.

The issue proposed an implicit nesting-depth counter. Verified on main, that does not work: the inner assertions are siblings, not nested — the first has already returned when the second starts, so both read depth 0. Detecting the enclosing assert_* frame instead would classify the inner assertion of assert_assertion_fails (#916) as nested and silence the counters its verdict detection reads, and would shift the totals of every suite already composing assertions. So this ships as an opt-in marker.

💡 Changes

  • Add bashunit::assert_once <label> <actual>: declared at the top of a custom assertion, it absorbs everything asserted inside into one reported assertion, labelled with the calling test.
  • Opt-in, so no existing totals change, assert_assertion_* keeps working, and repeated calls from a loop still count once each.
  • Bash has no cheap return hook, so the marker counts optimistically and the flush converts to a failure — totals stay correct at every point without observing the frame return.
  • Absorption hooks sit behind a plain global test in the four reporting choke points, keeping the per-assertion path flat.

… once
A custom assertion built out of built-in assertions counts one assertion per
inner step, and its failure names that step rather than the check the test
author wrote. `assert_http_success` composed from two comparisons reported 2
assertions per call and failed with "Expected '500' to be less than '300'".
Add an opt-in marker: `bashunit::assert_once <label> <actual>` at the top of a
custom assertion absorbs everything it asserts into a single reported
assertion, labelled with the test that called it.
The issue proposed an implicit nesting-depth counter. That does not work here:
the inner assertions are siblings, not nested frames -- the first has already
returned when the second starts, so both read depth 0. What distinguishes
composed from direct is an enclosing assert_* frame, and detecting that
implicitly would classify the inner assertion of assert_assertion_fails (#916)
as nested, silencing the very counters its verdict detection reads. An implicit
rule would also shift the totals of every suite already composing assertions.
Bash gives no cheap hook on a user function's return, so the marker counts one
passing assertion immediately and the flush converts it to a failure if
anything it absorbed failed. Totals are therefore correct at every point in
time without ever observing the declaring frame return. The marker is settled
by the next assert_once call (which is what makes a loop count once per
iteration), by an assertion reached after the declaring frame returned, or by
the end of the test.
The end-of-test flush runs from the EXIT trap, where the test frame is gone, so
the label is resolved eagerly at declaration time; otherwise failures were
reported as "Bashunit::assert::once flush".
Absorption hooks live in state::add_assertions_passed, assert::mark_failed,
console_results::print_failed_test and ::print_failure_message, each behind a
plain global test so the per-assertion path stays flat. assert::_capture saves
and restores the whole marker so #916 keeps working around it.
Closes#917
@ChemaclassChemaclass added the enhancement New feature or request label Jul 29, 2026
@ChemaclassChemaclass self-assigned this Jul 29, 2026
@Chemaclass
Chemaclass merged commit 96f25c3 into mainJul 29, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/917-composed-assertion-counts-once branch July 29, 2026 05:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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" + ' feat(assert): a composed assertion should count and report once by Chemaclass · Pull Request #921 · TypedDevs/bashunit · GitHub
Skip to content

feat(assert): a composed assertion should count and report once - #921

Merged
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once
Jul 29, 2026
Merged

feat(assert): a composed assertion should count and report once#921
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #917

A custom assertion composed from built-in ones counts one assertion per inner step, and its failure names that step rather than the check the test author wrote — assert_http_success reported 2 assertions per call and failed with Expected '500' to be less than '300'.

The issue proposed an implicit nesting-depth counter. Verified on main, that does not work: the inner assertions are siblings, not nested — the first has already returned when the second starts, so both read depth 0. Detecting the enclosing assert_* frame instead would classify the inner assertion of assert_assertion_fails (#916) as nested and silence the counters its verdict detection reads, and would shift the totals of every suite already composing assertions. So this ships as an opt-in marker.

💡 Changes

  • Add bashunit::assert_once <label> <actual>: declared at the top of a custom assertion, it absorbs everything asserted inside into one reported assertion, labelled with the calling test.
  • Opt-in, so no existing totals change, assert_assertion_* keeps working, and repeated calls from a loop still count once each.
  • Bash has no cheap return hook, so the marker counts optimistically and the flush converts to a failure — totals stay correct at every point without observing the frame return.
  • Absorption hooks sit behind a plain global test in the four reporting choke points, keeping the per-assertion path flat.

… once
A custom assertion built out of built-in assertions counts one assertion per
inner step, and its failure names that step rather than the check the test
author wrote. `assert_http_success` composed from two comparisons reported 2
assertions per call and failed with "Expected '500' to be less than '300'".
Add an opt-in marker: `bashunit::assert_once <label> <actual>` at the top of a
custom assertion absorbs everything it asserts into a single reported
assertion, labelled with the test that called it.
The issue proposed an implicit nesting-depth counter. That does not work here:
the inner assertions are siblings, not nested frames -- the first has already
returned when the second starts, so both read depth 0. What distinguishes
composed from direct is an enclosing assert_* frame, and detecting that
implicitly would classify the inner assertion of assert_assertion_fails (#916)
as nested, silencing the very counters its verdict detection reads. An implicit
rule would also shift the totals of every suite already composing assertions.
Bash gives no cheap hook on a user function's return, so the marker counts one
passing assertion immediately and the flush converts it to a failure if
anything it absorbed failed. Totals are therefore correct at every point in
time without ever observing the declaring frame return. The marker is settled
by the next assert_once call (which is what makes a loop count once per
iteration), by an assertion reached after the declaring frame returned, or by
the end of the test.
The end-of-test flush runs from the EXIT trap, where the test frame is gone, so
the label is resolved eagerly at declaration time; otherwise failures were
reported as "Bashunit::assert::once flush".
Absorption hooks live in state::add_assertions_passed, assert::mark_failed,
console_results::print_failed_test and ::print_failure_message, each behind a
plain global test so the per-assertion path stays flat. assert::_capture saves
and restores the whole marker so #916 keeps working around it.
Closes#917
@ChemaclassChemaclass added the enhancement New feature or request label Jul 29, 2026
@ChemaclassChemaclass self-assigned this Jul 29, 2026
@Chemaclass
Chemaclass merged commit 96f25c3 into mainJul 29, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/917-composed-assertion-counts-once branch July 29, 2026 05:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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('^' + ".*" + ' feat(assert): a composed assertion should count and report once by Chemaclass · Pull Request #921 · TypedDevs/bashunit · GitHub
Skip to content

feat(assert): a composed assertion should count and report once - #921

Merged
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once
Jul 29, 2026
Merged

feat(assert): a composed assertion should count and report once#921
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #917

A custom assertion composed from built-in ones counts one assertion per inner step, and its failure names that step rather than the check the test author wrote — assert_http_success reported 2 assertions per call and failed with Expected '500' to be less than '300'.

The issue proposed an implicit nesting-depth counter. Verified on main, that does not work: the inner assertions are siblings, not nested — the first has already returned when the second starts, so both read depth 0. Detecting the enclosing assert_* frame instead would classify the inner assertion of assert_assertion_fails (#916) as nested and silence the counters its verdict detection reads, and would shift the totals of every suite already composing assertions. So this ships as an opt-in marker.

💡 Changes

  • Add bashunit::assert_once <label> <actual>: declared at the top of a custom assertion, it absorbs everything asserted inside into one reported assertion, labelled with the calling test.
  • Opt-in, so no existing totals change, assert_assertion_* keeps working, and repeated calls from a loop still count once each.
  • Bash has no cheap return hook, so the marker counts optimistically and the flush converts to a failure — totals stay correct at every point without observing the frame return.
  • Absorption hooks sit behind a plain global test in the four reporting choke points, keeping the per-assertion path flat.

… once
A custom assertion built out of built-in assertions counts one assertion per
inner step, and its failure names that step rather than the check the test
author wrote. `assert_http_success` composed from two comparisons reported 2
assertions per call and failed with "Expected '500' to be less than '300'".
Add an opt-in marker: `bashunit::assert_once <label> <actual>` at the top of a
custom assertion absorbs everything it asserts into a single reported
assertion, labelled with the test that called it.
The issue proposed an implicit nesting-depth counter. That does not work here:
the inner assertions are siblings, not nested frames -- the first has already
returned when the second starts, so both read depth 0. What distinguishes
composed from direct is an enclosing assert_* frame, and detecting that
implicitly would classify the inner assertion of assert_assertion_fails (#916)
as nested, silencing the very counters its verdict detection reads. An implicit
rule would also shift the totals of every suite already composing assertions.
Bash gives no cheap hook on a user function's return, so the marker counts one
passing assertion immediately and the flush converts it to a failure if
anything it absorbed failed. Totals are therefore correct at every point in
time without ever observing the declaring frame return. The marker is settled
by the next assert_once call (which is what makes a loop count once per
iteration), by an assertion reached after the declaring frame returned, or by
the end of the test.
The end-of-test flush runs from the EXIT trap, where the test frame is gone, so
the label is resolved eagerly at declaration time; otherwise failures were
reported as "Bashunit::assert::once flush".
Absorption hooks live in state::add_assertions_passed, assert::mark_failed,
console_results::print_failed_test and ::print_failure_message, each behind a
plain global test so the per-assertion path stays flat. assert::_capture saves
and restores the whole marker so #916 keeps working around it.
Closes#917
@ChemaclassChemaclass added the enhancement New feature or request label Jul 29, 2026
@ChemaclassChemaclass self-assigned this Jul 29, 2026
@Chemaclass
Chemaclass merged commit 96f25c3 into mainJul 29, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/917-composed-assertion-counts-once branch July 29, 2026 05:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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('^' + ".*" + ' feat(assert): a composed assertion should count and report once by Chemaclass · Pull Request #921 · TypedDevs/bashunit · GitHub
Skip to content

feat(assert): a composed assertion should count and report once - #921

Merged
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once
Jul 29, 2026
Merged

feat(assert): a composed assertion should count and report once#921
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #917

A custom assertion composed from built-in ones counts one assertion per inner step, and its failure names that step rather than the check the test author wrote — assert_http_success reported 2 assertions per call and failed with Expected '500' to be less than '300'.

The issue proposed an implicit nesting-depth counter. Verified on main, that does not work: the inner assertions are siblings, not nested — the first has already returned when the second starts, so both read depth 0. Detecting the enclosing assert_* frame instead would classify the inner assertion of assert_assertion_fails (#916) as nested and silence the counters its verdict detection reads, and would shift the totals of every suite already composing assertions. So this ships as an opt-in marker.

💡 Changes

  • Add bashunit::assert_once <label> <actual>: declared at the top of a custom assertion, it absorbs everything asserted inside into one reported assertion, labelled with the calling test.
  • Opt-in, so no existing totals change, assert_assertion_* keeps working, and repeated calls from a loop still count once each.
  • Bash has no cheap return hook, so the marker counts optimistically and the flush converts to a failure — totals stay correct at every point without observing the frame return.
  • Absorption hooks sit behind a plain global test in the four reporting choke points, keeping the per-assertion path flat.

… once
A custom assertion built out of built-in assertions counts one assertion per
inner step, and its failure names that step rather than the check the test
author wrote. `assert_http_success` composed from two comparisons reported 2
assertions per call and failed with "Expected '500' to be less than '300'".
Add an opt-in marker: `bashunit::assert_once <label> <actual>` at the top of a
custom assertion absorbs everything it asserts into a single reported
assertion, labelled with the test that called it.
The issue proposed an implicit nesting-depth counter. That does not work here:
the inner assertions are siblings, not nested frames -- the first has already
returned when the second starts, so both read depth 0. What distinguishes
composed from direct is an enclosing assert_* frame, and detecting that
implicitly would classify the inner assertion of assert_assertion_fails (#916)
as nested, silencing the very counters its verdict detection reads. An implicit
rule would also shift the totals of every suite already composing assertions.
Bash gives no cheap hook on a user function's return, so the marker counts one
passing assertion immediately and the flush converts it to a failure if
anything it absorbed failed. Totals are therefore correct at every point in
time without ever observing the declaring frame return. The marker is settled
by the next assert_once call (which is what makes a loop count once per
iteration), by an assertion reached after the declaring frame returned, or by
the end of the test.
The end-of-test flush runs from the EXIT trap, where the test frame is gone, so
the label is resolved eagerly at declaration time; otherwise failures were
reported as "Bashunit::assert::once flush".
Absorption hooks live in state::add_assertions_passed, assert::mark_failed,
console_results::print_failed_test and ::print_failure_message, each behind a
plain global test so the per-assertion path stays flat. assert::_capture saves
and restores the whole marker so #916 keeps working around it.
Closes#917
@ChemaclassChemaclass added the enhancement New feature or request label Jul 29, 2026
@ChemaclassChemaclass self-assigned this Jul 29, 2026
@Chemaclass
Chemaclass merged commit 96f25c3 into mainJul 29, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/917-composed-assertion-counts-once branch July 29, 2026 05:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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); } })(); })(); feat(assert): a composed assertion should count and report once by Chemaclass · Pull Request #921 · TypedDevs/bashunit · GitHub
Skip to content

feat(assert): a composed assertion should count and report once - #921

Merged
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once
Jul 29, 2026
Merged

feat(assert): a composed assertion should count and report once#921
Chemaclass merged 1 commit into
mainfrom
feat/917-composed-assertion-counts-once

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #917

A custom assertion composed from built-in ones counts one assertion per inner step, and its failure names that step rather than the check the test author wrote — assert_http_success reported 2 assertions per call and failed with Expected '500' to be less than '300'.

The issue proposed an implicit nesting-depth counter. Verified on main, that does not work: the inner assertions are siblings, not nested — the first has already returned when the second starts, so both read depth 0. Detecting the enclosing assert_* frame instead would classify the inner assertion of assert_assertion_fails (#916) as nested and silence the counters its verdict detection reads, and would shift the totals of every suite already composing assertions. So this ships as an opt-in marker.

💡 Changes

  • Add bashunit::assert_once <label> <actual>: declared at the top of a custom assertion, it absorbs everything asserted inside into one reported assertion, labelled with the calling test.
  • Opt-in, so no existing totals change, assert_assertion_* keeps working, and repeated calls from a loop still count once each.
  • Bash has no cheap return hook, so the marker counts optimistically and the flush converts to a failure — totals stay correct at every point without observing the frame return.
  • Absorption hooks sit behind a plain global test in the four reporting choke points, keeping the per-assertion path flat.

… once
A custom assertion built out of built-in assertions counts one assertion per
inner step, and its failure names that step rather than the check the test
author wrote. `assert_http_success` composed from two comparisons reported 2
assertions per call and failed with "Expected '500' to be less than '300'".
Add an opt-in marker: `bashunit::assert_once <label> <actual>` at the top of a
custom assertion absorbs everything it asserts into a single reported
assertion, labelled with the test that called it.
The issue proposed an implicit nesting-depth counter. That does not work here:
the inner assertions are siblings, not nested frames -- the first has already
returned when the second starts, so both read depth 0. What distinguishes
composed from direct is an enclosing assert_* frame, and detecting that
implicitly would classify the inner assertion of assert_assertion_fails (#916)
as nested, silencing the very counters its verdict detection reads. An implicit
rule would also shift the totals of every suite already composing assertions.
Bash gives no cheap hook on a user function's return, so the marker counts one
passing assertion immediately and the flush converts it to a failure if
anything it absorbed failed. Totals are therefore correct at every point in
time without ever observing the declaring frame return. The marker is settled
by the next assert_once call (which is what makes a loop count once per
iteration), by an assertion reached after the declaring frame returned, or by
the end of the test.
The end-of-test flush runs from the EXIT trap, where the test frame is gone, so
the label is resolved eagerly at declaration time; otherwise failures were
reported as "Bashunit::assert::once flush".
Absorption hooks live in state::add_assertions_passed, assert::mark_failed,
console_results::print_failed_test and ::print_failure_message, each behind a
plain global test so the per-assertion path stays flat. assert::_capture saves
and restores the whole marker so #916 keeps working around it.
Closes#917
@ChemaclassChemaclass added the enhancement New feature or request label Jul 29, 2026
@ChemaclassChemaclass self-assigned this Jul 29, 2026
@Chemaclass
Chemaclass merged commit 96f25c3 into mainJul 29, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/917-composed-assertion-counts-once branch July 29, 2026 05:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Chemaclass