Skip to content

Form comparison and diffing (Delphi.Forms.Diff) #38

Description

@darianmiller

Add a library unit for comparing two TFormFile ASTs and producing a
structured diff. Useful for tools that show form-level changes between
commits, migration auditing, and CI pipelines that need to detect
component additions/removals/renames.

Design

TPropertyChange = record
  ComponentPath: string;   // e.g. 'Form1.Panel1.Button1'
  PropertyName: string;
  OldValue: string;        // preview text from FormValuePreview
  NewValue: string;
end;

TComponentChange = record
  Path: string;            // dot-separated path to the component
  ClassName: string;
  ObjectKind: TObjectKind;
end;

TFormDiff = record
  AddedComponents: TArray<TComponentChange>;
  RemovedComponents: TArray<TComponentChange>;
  ChangedProperties: TArray<TPropertyChange>;
  Identical: Boolean;
end;

class function CompareForms(A, B: TFormFile): TFormDiff;

Matching strategy

Components are matched by name path (e.g. Form1.Panel1.Button1).
A component present in B but not A is "added"; present in A but not B
is "removed". Matched components have their properties compared by name
-- differing values produce a TPropertyChange entry.

This name-based matching works for the common case (same form, different
versions). It does not handle component renames -- that would require
heuristic matching and is out of scope for the initial implementation.

Deliverables

  • source/Delphi.Forms.Diff.pas with CompareForms function
  • Recursive comparison of component trees by name path
  • Property comparison using FormValuePreview for value text
  • Add unit to test project .dpr and .dproj
  • Tests for: identical forms, added/removed components, changed
    properties, nested component changes, empty forms

Acceptance criteria

  • Identical forms produce Identical = True and empty arrays
  • Added/removed components detected at all nesting levels
  • Changed property values reported with old and new preview text
  • Component path accurately reflects nesting hierarchy
  • All existing tests still pass

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions