# Test Suite Migration Strategy

## Analysis

The test suite uses extensive template-based infrastructure in `FrStruct.hh`:

### Current Test Pattern

**Demote Testing** (lines 110-176):
```cpp
template<typename current_type, typename previous_type>
class Demote {
    static void ToPrevious(...) {
        obj->DemoteObject(PreviousSpecVersion, obj, NULL_ISTREAM);
        // Validates addresses, checks if same pointer returned
    }
};
```

**Promote Testing** (lines 230-350):
```cpp
template<typename current_type, typename previous_type>
class Promote {
    static void FromPrevious(...) {
        fr_object->PromoteObject(SpecVersion, PreviousSpecVersion, previous, NULL_ISTREAM);
        // Validates addresses, checks promotion behavior
    }
};
```

**Used via Macros**:
- `DEMOTE_TO_PREVIOUS_DIFF(CUR, PRE)` - ~20 uses
- `PROMOTE_FROM_NOTHING(CUR)` - ~15 uses
- `PROMOTE_FROM_PREVIOUS_DIFF(CUR, PRE)` - ~25 uses

## Problem

These tests validate functionality that **doesn't exist** in Universal objects:
- All promote/demote implementations return the object unchanged
- Tests just validate that same pointer is returned
- No actual version conversion happens

## Migration Options

### Option 1: Full Migration (Ideal, but extensive)

**Effort**: 2-3 weeks

**Approach**:
1. Create new I/O round-trip test infrastructure
2. Migrate all ~60 test usages
3. Write actual file I/O tests

**Example**:
```cpp
// NEW: Real I/O testing
template<typename ObjectType>
void test_version_io_compatibility(
    boost::shared_ptr<ObjectType> obj,
    int write_version,
    int read_version
) {
    // Write at one version
    std::string filename = "test_temp.gwf";
    OFrameStream out(filename);
    out.setStreamVersion(write_version);
    auto frame = make_test_frame_with_object(obj);
    out.WriteFrame(frame);
    out.close();

    // Read at different version
    IFrameStream in(filename);
    in.setMemoryVersion(read_version);
    auto frame_read = in.ReadFrame(0);
    auto obj_read = extract_object_from_frame<ObjectType>(frame_read);

    // Validate data integrity
    BOOST_CHECK(obj_read != nullptr);
    validate_object_fields(obj, obj_read);
}
```

### Option 2: Minimal Stub (Pragmatic, fast)

**Effort**: 1-2 days

**Approach**:
1. Keep test infrastructure but make it no-op
2. Add deprecation comments
3. Tests pass trivially (as they already do)
4. Leave proper testing for future work

**Implementation**:
```cpp
// In FrStruct.hh
template<typename current_type, typename previous_type>
class Demote {
    // DEPRECATED: Universal objects don't support demote
    // These tests validate nothing - promote/demote returns obj unchanged
    // TODO: Replace with I/O round-trip tests

    static void ToPrevious(...) {
        #ifdef ENABLE_LEGACY_PROMOTE_DEMOTE_TESTS
        current_type obj(...);
        boost::shared_ptr<FrObject> previous(
            obj->DemoteObject(PreviousSpecVersion, obj, NULL_ISTREAM));
        AddressCheck(previous.get(), obj.get(), false, true, Leader);
        #else
        // Stub - no-op test since Universal objects return unchanged
        BOOST_TEST_MESSAGE("DEPRECATED: Demote test disabled - Universal objects don't need version conversion");
        #endif
    }
};
```

### Option 3: Hybrid Approach (Recommended)

**Effort**: 3-5 days

**Phase 1 - Immediate** (1 day):
- Disable promote/demote tests via #ifdef guard
- Add clear deprecation notices
- Ensure build passes without warnings

**Phase 2 - Short term** (2-3 days):
- Create I/O round-trip infrastructure for 3-4 key object types
- Migrate highest-value tests (FrVect, FrAdcData, FrameH)
- Demonstrates the new pattern

**Phase 3 - Future**:
- Migrate remaining test files as needed
- Remove #ifdef guards once migration complete

## Recommendation

**Use Option 3 (Hybrid)** because:

✅ **Fast initial progress** - Remove infrastructure in 1 day
✅ **Proves the concept** - Shows how I/O testing should work
✅ **Incremental** - Can stop at any point
✅ **Low risk** - Old tests just disabled, not deleted

## Implementation Plan

### Step 1: Guard existing tests (30 minutes)

```cpp
// At top of FrStruct.hh
#ifndef ENABLE_LEGACY_PROMOTE_DEMOTE_TESTS
#define ENABLE_LEGACY_PROMOTE_DEMOTE_TESTS 0
#endif

// Wrap test infrastructure
#if ENABLE_LEGACY_PROMOTE_DEMOTE_TESTS
template<typename current_type, typename previous_type>
class Demote { ... };
template<typename current_type, typename previous_type>
class Promote { ... };
#else
// Stub implementations that just pass
template<typename current_type, typename previous_type>
class Demote {
    static void ToPrevious(...) { /* no-op */ }
    static void ToSame(...) { /* no-op */ }
    static previous_type Previous(...) { return previous_type(); }
};
// ... similar for Promote
#endif
```

### Step 2: Create I/O test infrastructure (2 hours)

```cpp
// New file: test/FrameIOTestHelpers.hh
namespace FrameIOTest {
    // Write frame with object at specific version
    template<typename ObjectType>
    void write_test_frame(const std::string& filename,
                          boost::shared_ptr<ObjectType> obj,
                          int version);

    // Read frame and extract object
    template<typename ObjectType>
    boost::shared_ptr<ObjectType> read_test_frame(
        const std::string& filename,
        int memory_version);

    // Full round-trip test
    template<typename ObjectType>
    void test_io_round_trip(boost::shared_ptr<ObjectType> obj,
                           int write_version,
                           int read_version);
}
```

### Step 3: Migrate key tests (1-2 days)

Priority order:
1. **FrVect** - Most complex, has compression
2. **FrAdcData** - Commonly used
3. **FrameH** - Core frame object
4. **FrProcData** - Representative of data objects

### Step 4: Remove infrastructure (see main removal plan)

Once tests pass with guards disabled:
- Remove promote/demote from FrameSpec
- Remove from FrObjectClassicIO
- Remove guarded test code
- Keep I/O test infrastructure

## Decision Point

**Question for you**: Which option do you prefer?

- **Option 1**: Full migration (2-3 weeks, most thorough)
- **Option 2**: Stub out tests (1-2 days, quickest)
- **Option 3**: Hybrid approach (3-5 days, balanced)

I recommend **Option 3** to make steady progress while proving the new approach works.
