GPT 5.5review32cb1ad4 months agoHistory
1206 lines · 41.1 KB · Rust
RawDownload
use gix_diff::{    Rewrites,    blob::DiffLineStats,    rewrites,    rewrites::{        Copies, CopySource,        tracker::{            ChangeKind,            visit::{Source, SourceKind},        },    },    tree::visit::Relation,};use gix_object::tree::EntryKind;use pretty_assertions::assert_eq; use crate::{    hex_to_id,    rewrites::{Change, NULL_ID},}; #[test]fn rename_by_id() -> crate::Result {    // Limits are only applied when doing rewrite-checks    for limit in [0, 1] {        let rewrites = Rewrites {            copies: None,            percentage: None,            limit,            track_empty: false,        };        let mut track = util::new_tracker(rewrites);        assert!(            track.try_push_change(Change::modification(), "a".into()).is_some(),            "modifications play no role in rename tracking"        );        assert!(            track.try_push_change(Change::deletion(), "b".into()).is_none(),            "recorded for later matching"        );        assert!(            track.try_push_change(Change::addition(), "c".into()).is_none(),            "recorded for later matching"        );        let mut called = false;        let out = util::assert_emit(&mut track, |dst, src| {            assert!(!called, "only one rename pair is expected");            called = true;            assert_eq!(                src.unwrap(),                Source {                    entry_mode: EntryKind::Blob.into(),                    id: *NULL_ID,                    kind: SourceKind::Rename,                    location: "b".into(),                    change: &Change::deletion(),                    diff: None,                }            );            assert_eq!(dst.location, "c");            std::ops::ControlFlow::Continue(())        });        assert_eq!(            out,            rewrites::Outcome {                options: rewrites,                ..Default::default()            },            "no similarity check was performed, it was all matched by id"        );    }    Ok(())} #[test]fn copy_by_similarity_reports_limit_if_encountered() -> crate::Result {    let rewrites = Rewrites {        copies: Some(Copies {            source: CopySource::FromSetOfModifiedFiles,            percentage: Some(0.5),        }),        percentage: None,        limit: 1,        track_empty: false,    };    let mut track = util::new_tracker(rewrites);    let odb = util::add_retained_blobs(        &mut track,        [            (Change::modification(), "a", "a\n"),            (Change::addition(), "a-cpy-1", "a"),            (Change::addition(), "a-cpy-2", "a"),            (Change::modification(), "d", "ab"),        ],    )?;     let mut calls = 0;    let out = util::assert_emit_with_objects(        &mut track,        |dst, src| {            assert!(src.is_none());            match calls {                0 => assert_eq!(dst.location, "a"),                1 => assert_eq!(dst.location, "a-cpy-1"),                2 => assert_eq!(dst.location, "a-cpy-2"),                3 => assert_eq!(dst.location, "d"),                _ => panic!("too many emissions"),            }            calls += 1;            std::ops::ControlFlow::Continue(())        },        odb,    );    assert_eq!(        out,        rewrites::Outcome {            options: rewrites,            num_similarity_checks_skipped_for_copy_tracking_due_to_limit: 4,            ..Default::default()        },        "no similarity check was performed at all - all or nothing"    );    Ok(())} #[test]fn copy_by_id() -> crate::Result {    // Limits are only applied when doing rewrite-checks    for limit in [0, 1] {        let rewrites = Rewrites {            copies: Some(Copies {                source: CopySource::FromSetOfModifiedFiles,                percentage: None,            }),            percentage: None,            limit,            track_empty: false,        };        let mut track = util::new_tracker(rewrites);        let odb = util::add_retained_blobs(            &mut track,            [                (Change::modification(), "a", "a"),                (Change::addition(), "a-cpy-1", "a"),                (Change::addition(), "a-cpy-2", "a"),                (Change::modification(), "d", "a"),            ],        )?;         let mut calls = 0;        let out = util::assert_emit_with_objects(            &mut track,            |dst, src| {                let id = hex_to_id(                    "2e65efe2a145dda7ee51d1741299f848e5bf752e",                    "eb337bcee2061c5313c9a1392116b6c76039e9e30d71467ae359b36277e17dc7",                );                let source_a = Source {                    entry_mode: EntryKind::Blob.into(),                    id,                    kind: SourceKind::Copy,                    location: "a".into(),                    change: &Change {                        id,                        ..Change::modification()                    },                    diff: None,                };                match calls {                    0 => {                        assert_eq!(src.unwrap(), source_a);                        assert_eq!(                            dst.location, "a-cpy-1",                            "it just finds the first possible match in order, ignoring other candidates"                        );                    }                    1 => {                        assert_eq!(src.unwrap(), source_a, "copy-sources can be used multiple times");                        assert_eq!(dst.location, "a-cpy-2");                    }                    2 => {                        assert!(src.is_none());                        assert_eq!(dst.location, "d");                    }                    _ => panic!("too many emissions"),                }                calls += 1;                std::ops::ControlFlow::Continue(())            },            odb,        );        assert_eq!(            out,            rewrites::Outcome {                options: rewrites,                ..Default::default()            },            "no similarity check was performed, it was all matched by id"        );    }    Ok(())} #[test]fn copy_by_id_search_in_all_sources() -> crate::Result {    // Limits are only applied when doing rewrite-checks    for limit in [0, 1] {        let rewrites = Rewrites {            copies: Some(Copies {                source: CopySource::FromSetOfModifiedFilesAndAllSources,                percentage: None,            }),            percentage: None,            limit,            track_empty: false,        };        let mut track = util::new_tracker(rewrites);        let odb = util::add_retained_blobs(            &mut track,            [                (Change::addition(), "a-cpy-1", "a"),                (Change::addition(), "a-cpy-2", "a"),            ],        )?;         let content_id = hex_to_id(            "2e65efe2a145dda7ee51d1741299f848e5bf752e",            "eb337bcee2061c5313c9a1392116b6c76039e9e30d71467ae359b36277e17dc7",        );         let mut calls = 0;        let out = util::assert_emit_with_objects_and_sources(            &mut track,            |dst, src| {                let source_a = Source {                    entry_mode: EntryKind::Blob.into(),                    id: content_id,                    kind: SourceKind::Copy,                    location: "a-src".into(),                    change: &Change {                        id: content_id,                        ..Change::modification()                    },                    diff: None,                };                match calls {                    0 => {                        assert_eq!(src.unwrap(), source_a);                        assert_eq!(                            dst.location, "a-cpy-1",                            "it just finds the first possible match in order, ignoring other candidates"                        );                    }                    1 => {                        assert_eq!(src.unwrap(), source_a, "copy-sources can be used multiple times");                        assert_eq!(dst.location, "a-cpy-2");                    }                    2 => {                        assert!(src.is_none());                        assert_eq!(dst.location, "d");                    }                    _ => panic!("too many emissions"),                }                calls += 1;                std::ops::ControlFlow::Continue(())            },            odb,            [(                {                    let mut c = Change::modification();                    c.id = content_id;                    c                },                "a-src",            )],        );        assert_eq!(            out,            rewrites::Outcome {                options: rewrites,                ..Default::default()            },            "no similarity check was performed, it was all matched by id"        );    }    Ok(())} #[test]fn copy_by_50_percent_similarity() -> crate::Result {    let rewrites = Rewrites {        copies: Some(Copies {            source: CopySource::FromSetOfModifiedFiles,            percentage: Some(0.5),        }),        percentage: None,        limit: 0,        track_empty: false,    };    let mut track = util::new_tracker(rewrites);    let odb = util::add_retained_blobs(        &mut track,        [            (Change::modification(), "a", "a\n"),            (Change::addition(), "a-cpy-1", "a\nb"),            (Change::addition(), "a-cpy-2", "a\nc"),            (Change::modification(), "d", "a"),        ],    )?;     let mut calls = 0;    let out = util::assert_emit_with_objects(        &mut track,        |dst, src| {            let id = hex_to_id(                "78981922613b2afb6025042ff6bd878ac1994e85",                "f8625e43f9e04f24291f77cdbe4c71b3c2a3b0003f60419b3ed06a058d766c8b",            );            let source_a = Source {                entry_mode: EntryKind::Blob.into(),                id,                kind: SourceKind::Copy,                location: "a".into(),                change: &Change {                    id,                    ..Change::modification()                },                diff: Some(DiffLineStats {                    removals: 0,                    insertions: 1,                    before: 1,                    after: 2,                    similarity: 0.6666667,                }),            };            match calls {                0 => {                    assert_eq!(                        src.unwrap(),                        source_a,                        "it finds the first possible source, no candidates"                    );                    assert_eq!(dst.location, "a-cpy-1");                }                1 => {                    assert_eq!(src.unwrap(), source_a, "the same source can be reused as well");                    assert_eq!(dst.location, "a-cpy-2");                }                2 => {                    assert!(src.is_none());                    assert_eq!(dst.location, "d");                }                _ => panic!("too many emissions"),            }            calls += 1;            std::ops::ControlFlow::Continue(())        },        odb,    );    assert_eq!(        out,        rewrites::Outcome {            options: rewrites,            num_similarity_checks: 4,            ..Default::default()        },        "no similarity check was performed, it was all matched by id"    );    Ok(())} #[test]fn copy_by_id_in_additions_only() -> crate::Result {    let rewrites = Rewrites {        copies: Some(Copies {            source: CopySource::FromSetOfModifiedFiles,            percentage: None,        }),        percentage: None,        limit: 0,        track_empty: false,    };    let mut track = util::new_tracker(rewrites);    let odb = util::add_retained_blobs(        &mut track,        [            (Change::modification(), "a", "a"),            (Change::modification(), "a-cpy-1", "a"),        ],    )?;     let mut calls = 0;    let out = util::assert_emit_with_objects(        &mut track,        |dst, src| {            match calls {                0 => {                    assert!(src.is_none());                    assert_eq!(dst.location, "a");                }                1 => {                    assert!(src.is_none());                    assert_eq!(                        dst.location, "a-cpy-1",                        "copy detection is only done for additions, not within modifications"                    );                }                _ => panic!("too many emissions"),            }            calls += 1;            std::ops::ControlFlow::Continue(())        },        odb,    );    assert_eq!(        out,        rewrites::Outcome {            options: rewrites,            ..Default::default()        },        "no similarity check was performed, it was all matched by id"    );    Ok(())} #[test]fn rename_by_similarity_reports_limit_if_encountered() -> crate::Result {    let rewrites = Rewrites {        copies: None,        percentage: Some(0.5),        limit: 1,        track_empty: false,    };    let mut track = util::new_tracker(rewrites);    let odb = util::add_retained_blobs(        &mut track,        [            (Change::deletion(), "a", "first\nsecond\n"),            (Change::addition(), "b", "firt\nsecond\n"),            (Change::addition(), "c", "second\nunrelated\n"),        ],    )?;     let mut calls = 0;    let out = util::assert_emit_with_objects(        &mut track,        |dst, src| {            assert!(src.is_none());            match calls {                0 => assert_eq!(dst.location, "a"),                1 => assert_eq!(dst.location, "b"),                2 => assert_eq!(dst.location, "c"),                _ => panic!("too many elements emitted"),            }            calls += 1;            std::ops::ControlFlow::Continue(())        },        odb,    );    assert_eq!(        out,        rewrites::Outcome {            options: rewrites,            num_similarity_checks_skipped_for_rename_tracking_due_to_limit: 2,            ..Default::default()        },        "no similarity check was performed at all - all or nothing"    );    Ok(())} #[test]fn rename_by_50_percent_similarity() -> crate::Result {    let rewrites = Rewrites {        copies: None,        percentage: Some(0.5),        limit: 0,        track_empty: false,    };    let mut track = util::new_tracker(rewrites);    let odb = util::add_retained_blobs(        &mut track,        [            (Change::deletion(), "a", "first\nsecond\n"),            (Change::addition(), "b", "firt\nsecond\n"),            (Change::addition(), "c", "second\nunrelated\n"),        ],    )?;     let mut calls = 0;    let out = util::assert_emit_with_objects(        &mut track,        |dst, src| {            match calls {                0 => {                    let id = hex_to_id(                        "66a52ee7a1d803dc57859c3e95ac9dcdc87c0164",                        "fdf2fd32de1d33ee5744979b40b07e0930a12c59dfbc5b3b6d34b807f944ba6e",                    );                    assert_eq!(

Lines 1–500 of 1206.