Skip to content

Latest commit

 

History

History
299 lines (221 loc) · 14.9 KB

File metadata and controls

299 lines (221 loc) · 14.9 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Bold for Delphi is a Model-Driven Architecture (MDA) framework and Object-Relational Mapping (ORM) tool. It enables UML-based model development with OCL (Object Constraint Language) queries, automatic code generation, and sophisticated database persistence. Originally released by Boldsoft in 2004, it was open-sourced by Embarcadero in 2020 under MIT license.

Current Version: 4.0.1.0 (community-maintained develop branch) Target Platforms: Delphi 11.3, 12.1, 12.3 and 13 (Win32/Win64)

Claude Code Instructions

By default never guess to generate the answer. If information is missing ask for clarification. Only guess if the prompt actually tells you to.

Important Paths (REMEMBER THESE!)

  • UnitTest.exe: C:\Attracs\BoldForDelphi\UnitTest\UnitTest.exe
  • UnitTest project folder: C:\Attracs\BoldForDelphi\UnitTest

Testing Strategy for Bold Source Changes

When modifying any code in Source/, follow this workflow:

1. Check Coverage First

Before making changes, check if the method(s) you're modifying have 100% test coverage.

  • Look at UnitTest/coverage_report/CodeCoverage_summary.html
  • If already 100% covered, proceed to step 4

2. Write Test First (if not fully covered)

Create a unit test that covers the code you're about to change:

  • For refactoring: Write a test that passes with current code
  • For bugfix: Write a test that FAILS with current code (demonstrates the bug)

3. Building Unit Tests (MANDATORY - USE EXACTLY)

Use the build.ps1 script - it properly sets DUnitX and DelphiMocks environment variables:

powershell -ExecutionPolicy Bypass -File "C:\Attracs\BoldForDelphi\UnitTest\build.ps1"

Why use build.ps1?

  • Sets $env:DUnitX and $env:DelphiMocks correctly
  • Avoids "Unit 'DUnitX.Loggers.Console' not found" errors
  • Works reliably from bash shell

DO NOT use inline env var setting - it fails due to bash-to-PowerShell transition issues:

# WRONG - env vars get mangled
powershell -Command "& { $env:DUnitX = '...'; ... }"

Running Specific Tests

The --run filter uses the full namespace path UnitName.ClassName[.TestName].

IMPORTANT: On Windows PowerShell, use this exact syntax to capture all output:

# From project root (C:\Attracs\BoldForDelphi)
powershell -Command "& '.\UnitTest\UnitTest.exe' --run:Test.BoldUndoHandler.TTestBoldUndoHandler --consolemode:Verbose 2>&1"

# Run ALL tests in a test class
powershell -Command "& '.\UnitTest\UnitTest.exe' --run:Test.BoldPMappersDefault.TTestBoldPMappersDefault 2>&1"

# Run ONE specific test
powershell -Command "& '.\UnitTest\UnitTest.exe' --run:Test.BoldPMappersDefault.TTestBoldPMappersDefault.TestMockQueryWithBoldDbTypeField 2>&1"

# Run with quiet output
powershell -Command "& '.\UnitTest\UnitTest.exe' --run:Test.BoldDBInterfacesMock.TTestBoldDBInterfacesMock --consolemode:Quiet 2>&1"

# Run with verbose output (recommended for debugging)
powershell -Command "& '.\UnitTest\UnitTest.exe' --run:Test.BoldUndoHandler.TTestBoldUndoHandler --consolemode:Verbose 2>&1"

Why this syntax?

  • powershell -Command "& '...' 2>&1" ensures both stdout and stderr are captured
  • Use single quotes around the exe path for paths with spaces
  • Always run from project root with .\UnitTest\UnitTest.exe path

4. Make the Source Change

Now implement your refactoring or bugfix in Bold source.

5. Run Full Coverage

powershell -ExecutionPolicy Bypass -File "C:\Attracs\BoldForDelphi\UnitTest\run_coverage.ps1"

6. Verify

  • All tests pass
  • Changed code is now covered in the coverage report

7. Upload Coverage to Codecov.io (optional)

# Convert coverage to Codecov JSON format
powershell -ExecutionPolicy Bypass -File "C:\Attracs\BoldForDelphi\UnitTest\Convert-ToCodecovJson.ps1"

# Upload (requires codecov.exe in repo root and CODECOV_TOKEN env var)
./codecov.exe -f "UnitTest/codecov.json"

See CODECOV_SETUP.md for full details.

Summary: Test-first for bugfixes (test fails then passes), test-first for refactoring (test passes before and after).

Git Commit Messages

Do not include Claude references in git commit messages. No "Generated with Claude", no "Co-Authored-By: Claude", and no similar attributions.

File Encoding

  • New Delphi units: Always use UTF-8 with BOM
  • Existing units: Convert to UTF-8 with BOM when modifying the file

Writing Unit Tests

When adding unit tests to improve code coverage:

  1. Focus on uncovered lines - Check the coverage report first. If a unit has 85/100 lines covered, write tests targeting the remaining 15 uncovered lines, not the already-covered code.

  2. Minimal tests for coverage - Write the minimum test code needed to exercise uncovered paths. Don't add redundant tests for code already covered by existing tests.

  3. Check what's already tested - Before writing tests, understand why existing coverage exists. Often, internal functions are exercised indirectly through other code paths.

  4. Target exception paths - Uncovered lines are often error handling or edge cases. These typically require specific test scenarios (invalid input, null values, etc.).

  5. One test per gap - If only one function/path is uncovered, one focused test is sufficient.

Example: If BoldFoo.pas has 97% coverage with only an exception handler uncovered, write a single test that triggers that exception - don't write additional tests for the already-covered happy paths.

Keeping README.md Updated

IMPORTANT: When adding or modifying unit tests, always update README.md with current statistics:

  1. After adding tests, update the README.md with:

    • Current number of unit tests (from test runner output: "Tests Found: XXX")
    • Current code coverage percentage (from coverage report summary)
  2. Location in README.md: Look for the testing/coverage section and update the numbers.

  3. How to get current values:

    # Run tests to get count
    powershell -Command "& '.\UnitTest\UnitTest.exe' --consolemode:Quiet 2>&1" | Select-String "Tests Found"
    
    # Run coverage to get percentage
    powershell -ExecutionPolicy Bypass -File "C:\Attracs\BoldForDelphi\UnitTest\run_coverage.ps1"
    # Check the summary output for "Covered %"
  4. Keep it accurate: The README.md is the public face of the project. Outdated test counts or coverage numbers mislead users about project quality.

Project Structure

BoldForDelphi/
├── packages/
│   ├── Delphi11.3/              ← Delphi 11.3 Alexandria
│   ├── Delphi12.1_CE/           ← Delphi 12.1 CE Athens
│   ├── Delphi12.3/              ← Delphi 12.3 Athens
│   │   ├── dclBold.dpk          (design-time package)
│   │   └── dclBold.dproj
│   ├── Delphi13/                ← Delphi 13
│   └── Bin/                     ← Compiled BPL output
├── Source/
│   ├── Common/
│   │   ├── Core/                ← Base classes: BoldBase, BoldContainers, BoldDefs
│   │   ├── Subscription/        ← Observer pattern: BoldSubscription, BoldDeriver
│   │   ├── Support/             ← Utilities: BoldUtils, BoldGuard, BoldIndex
│   │   └── Include/             ← Compiler directives: Bold.inc
│   ├── ObjectSpace/
│   │   ├── Core/                ← TBoldSystem, BoldElements
│   │   ├── BORepresentation/    ← BoldAttributes, BoldSystem
│   │   ├── Ocl/                 ← OCL parser and evaluator
│   │   ├── RTModel/             ← Runtime type information (BoldSystemRT)
│   │   └── Undo/                ← Undo/redo mechanism
│   ├── Persistence/
│   │   ├── Core/                ← Persistence controllers and handles
│   │   ├── DB/                  ← Database persistence base
│   │   └── FireDAC/             ← FireDAC adapter (recommended)
│   ├── PMapper/
│   │   ├── SQL/                 ← SQL generation: BoldSqlNodes, BoldSqlQueryGenerator
│   │   └── DbEvolutor/          ← Database schema evolution
│   ├── BoldAwareGUI/
│   │   ├── BoldControls/        ← Data-aware VCL: BoldGrid, BoldEdit, BoldComboBox
│   │   ├── ControlPacks/        ← Renderer/follower pattern for UI binding
│   │   └── Core/                ← BoldGUI base functionality
│   ├── Handles/                 ← TBoldSystemHandle, TBoldListHandle, TBoldExpressionHandle
│   ├── MoldModel/
│   │   ├── Core/                ← Model representation (Mold = Model of Objects)
│   │   └── CodeGenerator/       ← Delphi code generation
│   └── UMLModel/
│       ├── Core/                ← UML metamodel (BoldUMLModel.pas)
│       ├── Editor/              ← Model editor UI
│       └── ModelLinks/          ← XMI, Rose98 integration
└── UnitTest/                    ← DUnitX tests

Folders to Ignore

  • Source/Deprecated/ - Contains deprecated database adapters (ADO, BDE, Advantage, DBExpress). Not used, not maintained. Ignore when searching for cleanup opportunities.

Build Commands for Delphi projects and packages

  • PowerShell script C:\Attracs\DelphiStandards\DelphiBuildDPROJ.ps1 This script in Powershell detect latest Delphi version and use that. -DelphiVersion override used Delphi. Read comments in the script for all details.

Example: Build MasterDetail project With latest Delphi (Delphi 13) and when Current folder is C:\Attracs\boldfordelphi

C:\Attracs\DelphiStandards\DelphiBuildDPROJ.ps1 -Projectfile "examples\Simple\ObjectSpace\MasterDetail\MasterDetail.dproj" -DelphiVersion "37.0" -VerboseOutPut

Example: Build Bold package for Delphi 12.3

C:\Attracs\DelphiStandards\DelphiBuildDPROJ.ps1 -Projectfile "packages\Delphi29.3\dclBold.dproj" -DelphiVersion "23.0" -VerboseOutPut

Environment Setup

Core Bold packages use relative paths and require no environment variable setup. Clone/copy the repository to any location and build.

Optional: For UniDAC support, set the UniDAC environment variable in Delphi (Tools > Options > Environment Variables) pointing to the UniDAC installation root.

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                    UML Model Editor                             │
│         (BoldUMLModel, XMI/Rose import/export)                 │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                Code Generator (MoldModel)                       │
│    Generates BusinessClasses.pas from UML model                │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│              ObjectSpace (Runtime Object Model)                 │
│  TBoldSystem, TBoldObject, TBoldAttribute, TBoldObjectList     │
│         OCL Query Engine (BoldOcl, BoldOclEvaluator)           │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│           Persistence Layer (PMapper, Persistence)             │
│     Object-Relational Mapping, SQL Generation, DB Evolution    │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│              Database Adapters (FireDAC, UniDAC, etc.)         │
│         SQL Server, PostgreSQL, InterBase, Oracle, etc.        │
└─────────────────────────────────────────────────────────────────┘

Key Packages

Package Type Purpose
dclBold.dpk Design-time Main Bold components for IDE integration
dclBoldUniDAC.dpk Design-time UniDAC database adapter components
dclBoldDevEx.dpk Design-time DevExpress integration components

Compiler Directives (Bold.inc)

The {$DEFINE Attracs} block at end of Bold.inc enables optimizations used by Attracs. When Attracs is NOT defined, several features are disabled for broader compatibility.

Key defines (enabled when Attracs is defined):

{$DEFINE SpanFetch}                          // Efficient batch fetching
{$DEFINE IDServer}                           // External ID server (improves write perf)
{$DEFINE CompareToOldValues}                 // Skip unchanged values in updates
{$DEFINE NoNegativeDates}                    // Restrict date range validation
{$DEFINE NoTransientInstancesOfPersistentClass}  // Performance optimization

Other notable defines:

{$DEFINE BoldJson}           // JSON serialization support (always on)
{$DEFINE BOLD_NO_QUERIES}    // Turns off query mechanism (always on)

Key Concepts

Object Constraint Language (OCL)

OCL is used for queries and constraints:

self.allInstances                    // All instances of a class
self.customers->select(age > 30)     // Filter collection
self.orders->collect(total)->sum     // Aggregate

Subscription Pattern

Bold uses a sophisticated subscription system for automatic UI updates when objects change. Components subscribe to objects/attributes and receive notifications on changes.

Resources