Skip to content

Any body edit alongside a rename loses the rename AND the behaviour change #45

Description

@n1ckyb

Found by two independent UAT testers, reproduced on the 0.0.2b1 wheel.

Extracting a helper destroys rename detection, and the behaviour change disappears entirely.

Reproduction

old.py

import os
import sys

def calculate_total(items):
    total = 0
    for i in items:
        total += i.price * i.qty
    return min(total, 50)

new.py — rename, extract a helper, and change one literal

import sys
import os

def _subtotal(i):
    return i.price * i.qty

def compute_order_total(items):
    total = 0
    for i in items:
        total += _subtotal(i)
    return min(total, 75)
$ intentumdiff file old.py new.py
| Changes   3      |
| DELETION | Delete function_definition('calculate_total')        |
| ADDITION | Insert -> function_definition('_subtotal')           |
| ADDITION | Insert -> function_definition('compute_order_total') |

Two defects

1. The rename is not detected. A delete/add pair is exactly what a line diff gives. The control proves the capability exists and is specifically lost:

$ intentumdiff file o2.py n2.py     # rename ALONE, nothing else
| REFACTORING | Rename function_definition('calculate_total') -> ('compute_order_total') |

So rename detection works — until a helper is extracted alongside it. That is the realistic case: people rename while refactoring.

2. The behaviour change is missing. min(total, 50)min(total, 75) raises the discount cap by 50% and appears nowhere in the output. Three changes reported, all structural. A reviewer trusting this sees a refactor and approves it.

The second is worse than the first. A missed rename is a weaker answer; a missed behaviour change is a wrong one.

This is the headline claim

The product's pitch is telling a refactor from a real change. On the canonical refactor — extract method plus rename — it does neither: no refactoring reported, and the one behaviour change swallowed.

On 0.0.1 it failed differently, and confidently

The VS Code UAT (extension 0.0.2-beta.1 against engine 0.0.1, the only combination installable today) got a wrong answer at full confidence rather than no answer:

Refactoring · Internal · Renamed calculate_total -> _subtotal   (100%)
Meaningful  · Behavior · Added function compute_order_total

The rename points at the newly extracted helper, and the renamed original is reported as a new function — the two categories inverted, asserted at 100%. Whatever changed between 0.0.1 and 0.0.2b1 removed the false positive but did not produce a correct answer.

Expected

  • compute_order_total recognised as the rename of calculate_total
  • _subtotal recognised as an extraction, not an unrelated addition
  • The 5075 change reported as a meaningful behaviour change, prominently

Fix should include

Per the repo rule, both a Rust #[cfg(test)] test and a Python acceptance test, using this exact fixture — rename + extraction + one literal change in a single file. It is small, canonical, and currently answered wrongly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions