diff --git a/dbt-project/models/marts/order_events_incremental.sql b/dbt-project/models/marts/order_events_incremental.sql
index 07a9ca90..88e3af22 100644
--- a/dbt-project/models/marts/order_events_incremental.sql
+++ b/dbt-project/models/marts/order_events_incremental.sql
@@ -1,7 +1,7 @@
-- SPIKE (cute-dbt#145 discovery) — incremental model to inspect how fusion
-- serializes `given: - input: this`, config.materialized, and overrides in
-- manifest.json. May become the committed dogfood fixture after shaping.
-{{ config(materialized='incremental', unique_key='order_id') }}
+{{ config(materialized='incremental', unique_key='order_id', incremental_strategy='merge') }}
with orders as (
select * from {{ ref('stg_orders') }}
diff --git a/examples/diff-showcase-report.html b/examples/diff-showcase-report.html
index e9076e4b..a513f051 100644
--- a/examples/diff-showcase-report.html
+++ b/examples/diff-showcase-report.html
@@ -5070,9 +5070,9 @@
Expected
.addClass("mode-badge " + (incrementalMode ? "mode-incremental" : "mode-full-refresh"))
.text(incrementalMode ? "incremental branch" : "full-refresh branch"));
if (incrementalMode) {
- var tip = "For an incremental-mode unit test, Expected is the result of the "
- + "materialization — the rows that will be merged or inserted — "
- + "not the resulting model itself (the final table after the merge).";
+ var tip = "Expected is the output of the model's compiled SELECT on the "
+ + "incremental branch — the rows the configured incremental strategy "
+ + "will apply to the table — not the table's final state after the run.";
// A focusable carrying a CSS-rendered bubble shown on hover
// AND keyboard focus — a native `title` is hover-delayed, keyboard-
// unreachable, and frequently never paints (cute-dbt#146 review). The
diff --git a/examples/jaffle-shop-report.html b/examples/jaffle-shop-report.html
index e9507c70..c8787791 100644
--- a/examples/jaffle-shop-report.html
+++ b/examples/jaffle-shop-report.html
@@ -5036,9 +5036,9 @@ Expected
.addClass("mode-badge " + (incrementalMode ? "mode-incremental" : "mode-full-refresh"))
.text(incrementalMode ? "incremental branch" : "full-refresh branch"));
if (incrementalMode) {
- var tip = "For an incremental-mode unit test, Expected is the result of the "
- + "materialization — the rows that will be merged or inserted — "
- + "not the resulting model itself (the final table after the merge).";
+ var tip = "Expected is the output of the model's compiled SELECT on the "
+ + "incremental branch — the rows the configured incremental strategy "
+ + "will apply to the table — not the table's final state after the run.";
// A focusable carrying a CSS-rendered bubble shown on hover
// AND keyboard focus — a native `title` is hover-delayed, keyboard-
// unreachable, and frequently never paints (cute-dbt#146 review). The
diff --git a/examples/playground-report.html b/examples/playground-report.html
index 5cd86eb0..0b06dad8 100644
--- a/examples/playground-report.html
+++ b/examples/playground-report.html
@@ -5036,9 +5036,9 @@ Expected
.addClass("mode-badge " + (incrementalMode ? "mode-incremental" : "mode-full-refresh"))
.text(incrementalMode ? "incremental branch" : "full-refresh branch"));
if (incrementalMode) {
- var tip = "For an incremental-mode unit test, Expected is the result of the "
- + "materialization — the rows that will be merged or inserted — "
- + "not the resulting model itself (the final table after the merge).";
+ var tip = "Expected is the output of the model's compiled SELECT on the "
+ + "incremental branch — the rows the configured incremental strategy "
+ + "will apply to the table — not the table's final state after the run.";
// A focusable carrying a CSS-rendered bubble shown on hover
// AND keyboard focus — a native `title` is hover-delayed, keyboard-
// unreachable, and frequently never paints (cute-dbt#146 review). The
diff --git a/features/incremental_models.feature b/features/incremental_models.feature
index 671c9b92..0332cdec 100644
--- a/features/incremental_models.feature
+++ b/features/incremental_models.feature
@@ -49,7 +49,7 @@ Feature: cute-dbt surfaces incremental-model unit-test semantics
And the unit test "test_order_events_incremental" overrides is_incremental to true
When I render the incremental report
Then the section for "test_order_events_incremental" marks the test as exercising the incremental branch
- And the section for "test_order_events_incremental" explains that Expected is the rows merged or inserted, not the final table
+ And the section for "test_order_events_incremental" explains the incremental expect semantics
Scenario: A full-refresh-mode unit test shows a full-refresh badge and no expect-semantics tooltip
Given the model "order_events" is materialized "incremental"
@@ -58,7 +58,7 @@ Feature: cute-dbt surfaces incremental-model unit-test semantics
And the unit test "test_order_events_full_refresh" overrides is_incremental to false
When I render the incremental report
Then the section for "test_order_events_full_refresh" marks the test as exercising the full-refresh branch
- And the section for "test_order_events_full_refresh" does not explain the merged-rows expect semantics
+ And the section for "test_order_events_full_refresh" does not explain the incremental expect semantics
Scenario: A given input of `this` is marked as the prior model state
Given the model "order_events" is materialized "incremental"
@@ -76,4 +76,4 @@ Feature: cute-dbt surfaces incremental-model unit-test semantics
And "orders" declares unit test "test_orders"
When I render the incremental report
Then the section for "test_orders" does not mark the test with an incremental or full-refresh branch
- And the section for "test_orders" does not explain the merged-rows expect semantics
+ And the section for "test_orders" does not explain the incremental expect semantics
diff --git a/templates/report.html b/templates/report.html
index b05d7512..8f36ffe6 100644
--- a/templates/report.html
+++ b/templates/report.html
@@ -1454,9 +1454,9 @@ Expected
.addClass("mode-badge " + (incrementalMode ? "mode-incremental" : "mode-full-refresh"))
.text(incrementalMode ? "incremental branch" : "full-refresh branch"));
if (incrementalMode) {
- var tip = "For an incremental-mode unit test, Expected is the result of the "
- + "materialization — the rows that will be merged or inserted — "
- + "not the resulting model itself (the final table after the merge).";
+ var tip = "Expected is the output of the model's compiled SELECT on the "
+ + "incremental branch — the rows the configured incremental strategy "
+ + "will apply to the table — not the table's final state after the run.";
// A focusable carrying a CSS-rendered bubble shown on hover
// AND keyboard focus — a native `title` is hover-delayed, keyboard-
// unreachable, and frequently never paints (cute-dbt#146 review). The
diff --git a/tests/headless_toggle.rs b/tests/headless_toggle.rs
index fc801726..ec48fc9e 100644
--- a/tests/headless_toggle.rs
+++ b/tests/headless_toggle.rs
@@ -3204,19 +3204,30 @@ fn incremental_badges_modes_tooltip_and_this_given() {
);
// The dbt gotcha wording lives in the VISIBLE CSS bubble AND the aria-label.
// Assert an ASCII substring — the tip contains em-dashes (U+2014), so a
- // full-string compare would mismatch.
+ // full-string compare would mismatch. cute-dbt#159: the copy is now
+ // strategy-invariant ("the rows the configured incremental strategy will
+ // apply to the table") — true for all 5 strategies, where the old
+ // "merged or inserted" was wrong for insert_overwrite / microbatch.
+ let bubble_text = eval_string(
+ &tab,
+ &format!("{TOOLTIP}.querySelector('.expect-tooltip-bubble').textContent"),
+ );
assert!(
- eval_string(
- &tab,
- &format!("{TOOLTIP}.querySelector('.expect-tooltip-bubble').textContent")
- )
- .contains("merged or inserted"),
- "the visible tooltip bubble explains Expected is the rows merged or inserted",
+ bubble_text.contains("incremental strategy will apply to the table"),
+ "the visible tooltip bubble explains Expected is the rows the strategy applies, got {bubble_text:?}",
+ );
+ assert!(
+ !bubble_text.contains("merged or inserted"),
+ "the bubble must NOT carry the old merge/append-centric wording (cute-dbt#159), got {bubble_text:?}",
+ );
+ let aria = eval_string(&tab, &format!("{TOOLTIP}.getAttribute('aria-label')"));
+ assert!(
+ aria.contains("incremental strategy will apply to the table"),
+ "the tooltip aria-label carries the same strategy-invariant wording (a11y parity), got {aria:?}",
);
assert!(
- eval_string(&tab, &format!("{TOOLTIP}.getAttribute('aria-label')"))
- .contains("merged or inserted"),
- "the tooltip aria-label carries the same dbt wording (a11y parity)",
+ !aria.contains("merged or inserted"),
+ "the aria-label must NOT carry the old merge/append-centric wording (cute-dbt#159), got {aria:?}",
);
// cute-dbt#146 review — the regression guard for "hover shows nothing": the
// bubble is hidden until hover/focus, and FOCUS reveals it (the keyboard
diff --git a/tests/snapshots/render_integration__rendered_chrome_jaffle_shop.snap b/tests/snapshots/render_integration__rendered_chrome_jaffle_shop.snap
index a4cdb37f..561fa43a 100644
--- a/tests/snapshots/render_integration__rendered_chrome_jaffle_shop.snap
+++ b/tests/snapshots/render_integration__rendered_chrome_jaffle_shop.snap
@@ -1403,9 +1403,9 @@ th.col-removed { text-decoration: line-through; text-decoration-color: rgba(190,
.addClass("mode-badge " + (incrementalMode ? "mode-incremental" : "mode-full-refresh"))
.text(incrementalMode ? "incremental branch" : "full-refresh branch"));
if (incrementalMode) {
- var tip = "For an incremental-mode unit test, Expected is the result of the "
- + "materialization — the rows that will be merged or inserted — "
- + "not the resulting model itself (the final table after the merge).";
+ var tip = "Expected is the output of the model's compiled SELECT on the "
+ + "incremental branch — the rows the configured incremental strategy "
+ + "will apply to the table — not the table's final state after the run.";
// A focusable carrying a CSS-rendered bubble shown on hover
// AND keyboard focus — a native `title` is hover-delayed, keyboard-
// unreachable, and frequently never paints (cute-dbt#146 review). The
diff --git a/tests/steps/incremental_models.rs b/tests/steps/incremental_models.rs
index 21c42184..9c435510 100644
--- a/tests/steps/incremental_models.rs
+++ b/tests/steps/incremental_models.rs
@@ -199,30 +199,30 @@ fn test_full_refresh_branch(world: &mut World, test: String) {
);
}
-#[then(
- regex = r#"^the section for "([^"]+)" explains that Expected is the rows merged or inserted, not the final table$"#
-)]
-fn explains_merged_rows(world: &mut World, test: String) {
+#[then(regex = r#"^the section for "([^"]+)" explains the incremental expect semantics$"#)]
+fn explains_incremental_expect(world: &mut World, test: String) {
// The expect-semantics tooltip rides the authoritative payload bool: it
// renders iff is_incremental_mode === true. cucumber asserts that
// driving payload fact; `headless_toggle.rs` asserts the rendered text.
+ // cute-dbt#159: the rendered copy is strategy-invariant (true for all 5
+ // incremental strategies, not just merge/append).
let p = payload(world);
let t = find_test(&p, &test);
assert_eq!(
t["is_incremental_mode"].as_bool(),
Some(true),
- "the merged-rows tooltip requires is_incremental_mode===true; got {t}"
+ "the incremental expect-semantics tooltip requires is_incremental_mode===true; got {t}"
);
}
-#[then(regex = r#"^the section for "([^"]+)" does not explain the merged-rows expect semantics$"#)]
-fn no_merged_rows_tooltip(world: &mut World, test: String) {
+#[then(regex = r#"^the section for "([^"]+)" does not explain the incremental expect semantics$"#)]
+fn no_incremental_expect_tooltip(world: &mut World, test: String) {
let p = payload(world);
let t = find_test(&p, &test);
assert_ne!(
t["is_incremental_mode"].as_bool(),
Some(true),
- "the merged-rows tooltip must be absent unless is_incremental_mode===true; got {t}"
+ "the incremental expect-semantics tooltip must be absent unless is_incremental_mode===true; got {t}"
);
}