|
| 1 | +//! Unit tests for object_diff module |
| 2 | +//! |
| 3 | +//! These tests verify that verbs with multiple names are counted correctly |
| 4 | +//! (as single verbs, not multiple) in ObjectChange tracking. |
| 5 | +
|
| 6 | +use moor_vcs_worker::object_diff::{compare_object_definitions_with_meta, ObjectChange}; |
| 7 | +use moor_compiler::ObjectDefinition; |
| 8 | + |
| 9 | +// Helper function to create a verb definition with multiple names |
| 10 | +fn create_verb_def(names: Vec<&str>) -> moor_compiler::ObjVerbDef { |
| 11 | + use moor_compiler::ObjVerbDef; |
| 12 | + use moor_var::{Symbol, Obj, program::ProgramType}; |
| 13 | + use moor_common::model::VerbArgsSpec; |
| 14 | + use moor_common::util::BitEnum; |
| 15 | + |
| 16 | + ObjVerbDef { |
| 17 | + names: names.iter().map(|n| Symbol::mk(n)).collect(), |
| 18 | + argspec: VerbArgsSpec::this_none_this(), |
| 19 | + owner: Obj::mk_id(1), |
| 20 | + flags: BitEnum::new(), |
| 21 | + program: ProgramType::MooR(Default::default()), |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +// Helper function to create a property definition |
| 26 | +fn create_prop_def(name: &str, value: moor_var::Var) -> moor_compiler::ObjPropDef { |
| 27 | + use moor_compiler::ObjPropDef; |
| 28 | + use moor_var::{Symbol, Obj}; |
| 29 | + use moor_common::model::{PropPerms, PropFlag}; |
| 30 | + use moor_common::util::BitEnum; |
| 31 | + |
| 32 | + ObjPropDef { |
| 33 | + name: Symbol::mk(name), |
| 34 | + perms: PropPerms::new(Obj::mk_id(1), BitEnum::<PropFlag>::new()), |
| 35 | + value: Some(value), |
| 36 | + } |
| 37 | +} |
| 38 | + |
| 39 | +// Helper function to create a basic object definition |
| 40 | +fn create_object_def() -> ObjectDefinition { |
| 41 | + use moor_var::Obj; |
| 42 | + use moor_common::util::BitEnum; |
| 43 | + |
| 44 | + ObjectDefinition { |
| 45 | + oid: Obj::mk_id(1), |
| 46 | + parent: Obj::mk_id(0), |
| 47 | + location: Obj::mk_id(0), |
| 48 | + owner: Obj::mk_id(1), |
| 49 | + name: "test".to_string(), |
| 50 | + flags: BitEnum::new(), |
| 51 | + verbs: vec![], |
| 52 | + property_definitions: vec![], |
| 53 | + property_overrides: vec![], |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +#[test] |
| 58 | +fn test_verb_with_multiple_names_added() { |
| 59 | + // Test that a verb with multiple names is counted as ONE verb added, not multiple |
| 60 | + let baseline = create_object_def(); |
| 61 | + |
| 62 | + let mut local = create_object_def(); |
| 63 | + // Add a verb with 3 names: "@foo", "foo", "bar" |
| 64 | + local.verbs.push(create_verb_def(vec!["@foo", "foo", "bar"])); |
| 65 | + |
| 66 | + let mut object_change = ObjectChange::new("test".to_string()); |
| 67 | + compare_object_definitions_with_meta(&baseline, &local, &mut object_change, None, None, None, None); |
| 68 | + |
| 69 | + // Should only count as ONE verb added |
| 70 | + assert_eq!(object_change.verbs_added.len(), 1, |
| 71 | + "Expected 1 verb added, got {}: {:?}", |
| 72 | + object_change.verbs_added.len(), |
| 73 | + object_change.verbs_added); |
| 74 | + |
| 75 | + // Should be empty |
| 76 | + assert_eq!(object_change.verbs_modified.len(), 0); |
| 77 | + assert_eq!(object_change.verbs_deleted.len(), 0); |
| 78 | +} |
| 79 | + |
| 80 | +#[test] |
| 81 | +fn test_verb_with_multiple_names_deleted() { |
| 82 | + // Test that a verb with multiple names is counted as ONE verb deleted |
| 83 | + let mut baseline = create_object_def(); |
| 84 | + baseline.verbs.push(create_verb_def(vec!["@foo", "foo", "bar"])); |
| 85 | + |
| 86 | + let local = create_object_def(); |
| 87 | + |
| 88 | + let mut object_change = ObjectChange::new("test".to_string()); |
| 89 | + compare_object_definitions_with_meta(&baseline, &local, &mut object_change, None, None, None, None); |
| 90 | + |
| 91 | + // Should only count as ONE verb deleted |
| 92 | + assert_eq!(object_change.verbs_deleted.len(), 1, |
| 93 | + "Expected 1 verb deleted, got {}: {:?}", |
| 94 | + object_change.verbs_deleted.len(), |
| 95 | + object_change.verbs_deleted); |
| 96 | + |
| 97 | + assert_eq!(object_change.verbs_added.len(), 0); |
| 98 | + assert_eq!(object_change.verbs_modified.len(), 0); |
| 99 | +} |
| 100 | + |
| 101 | +#[test] |
| 102 | +fn test_verb_with_multiple_names_modified() { |
| 103 | + // Test that a verb with multiple names is counted as ONE verb modified |
| 104 | + let mut baseline = create_object_def(); |
| 105 | + baseline.verbs.push(create_verb_def(vec!["@foo", "foo", "bar"])); |
| 106 | + |
| 107 | + let mut local = create_object_def(); |
| 108 | + let mut modified_verb = create_verb_def(vec!["@foo", "foo", "bar"]); |
| 109 | + // Change the owner to make it different |
| 110 | + modified_verb.owner = moor_var::Obj::mk_id(2); |
| 111 | + local.verbs.push(modified_verb); |
| 112 | + |
| 113 | + let mut object_change = ObjectChange::new("test".to_string()); |
| 114 | + compare_object_definitions_with_meta(&baseline, &local, &mut object_change, None, None, None, None); |
| 115 | + |
| 116 | + // Should only count as ONE verb modified |
| 117 | + assert_eq!(object_change.verbs_modified.len(), 1, |
| 118 | + "Expected 1 verb modified, got {}: {:?}", |
| 119 | + object_change.verbs_modified.len(), |
| 120 | + object_change.verbs_modified); |
| 121 | + |
| 122 | + assert_eq!(object_change.verbs_added.len(), 0); |
| 123 | + assert_eq!(object_change.verbs_deleted.len(), 0); |
| 124 | +} |
| 125 | + |
| 126 | +#[test] |
| 127 | +fn test_multiple_verbs_with_multiple_names() { |
| 128 | + // Test multiple verbs, each with multiple names |
| 129 | + let baseline = create_object_def(); |
| 130 | + |
| 131 | + let mut local = create_object_def(); |
| 132 | + local.verbs.push(create_verb_def(vec!["@foo", "foo", "bar"])); |
| 133 | + local.verbs.push(create_verb_def(vec!["@baz", "baz"])); |
| 134 | + local.verbs.push(create_verb_def(vec!["single"])); |
| 135 | + |
| 136 | + let mut object_change = ObjectChange::new("test".to_string()); |
| 137 | + compare_object_definitions_with_meta(&baseline, &local, &mut object_change, None, None, None, None); |
| 138 | + |
| 139 | + // Should count as THREE verbs added (not 6) |
| 140 | + assert_eq!(object_change.verbs_added.len(), 3, |
| 141 | + "Expected 3 verbs added, got {}: {:?}", |
| 142 | + object_change.verbs_added.len(), |
| 143 | + object_change.verbs_added); |
| 144 | +} |
| 145 | + |
| 146 | +#[test] |
| 147 | +fn test_mixed_verb_operations() { |
| 148 | + // Test a complex scenario with added, modified, and deleted verbs |
| 149 | + let mut baseline = create_object_def(); |
| 150 | + baseline.verbs.push(create_verb_def(vec!["@keep", "keep"])); |
| 151 | + baseline.verbs.push(create_verb_def(vec!["@delete", "delete", "del"])); |
| 152 | + |
| 153 | + let mut local = create_object_def(); |
| 154 | + // Keep one verb but modify it |
| 155 | + let mut modified = create_verb_def(vec!["@keep", "keep"]); |
| 156 | + modified.owner = moor_var::Obj::mk_id(2); |
| 157 | + local.verbs.push(modified); |
| 158 | + // Add a new verb |
| 159 | + local.verbs.push(create_verb_def(vec!["@new", "new", "n"])); |
| 160 | + |
| 161 | + let mut object_change = ObjectChange::new("test".to_string()); |
| 162 | + compare_object_definitions_with_meta(&baseline, &local, &mut object_change, None, None, None, None); |
| 163 | + |
| 164 | + assert_eq!(object_change.verbs_modified.len(), 1, |
| 165 | + "Expected 1 verb modified, got {}", object_change.verbs_modified.len()); |
| 166 | + assert_eq!(object_change.verbs_added.len(), 1, |
| 167 | + "Expected 1 verb added, got {}", object_change.verbs_added.len()); |
| 168 | + assert_eq!(object_change.verbs_deleted.len(), 1, |
| 169 | + "Expected 1 verb deleted, got {}", object_change.verbs_deleted.len()); |
| 170 | +} |
| 171 | + |
| 172 | +#[test] |
| 173 | +fn test_properties_are_not_affected() { |
| 174 | + // Verify that properties work correctly (they should, since they have single names) |
| 175 | + let baseline = create_object_def(); |
| 176 | + |
| 177 | + let mut local = create_object_def(); |
| 178 | + local.property_definitions.push(create_prop_def("prop1", moor_var::v_int(42))); |
| 179 | + local.property_definitions.push(create_prop_def("prop2", moor_var::v_str("test"))); |
| 180 | + |
| 181 | + let mut object_change = ObjectChange::new("test".to_string()); |
| 182 | + compare_object_definitions_with_meta(&baseline, &local, &mut object_change, None, None, None, None); |
| 183 | + |
| 184 | + // Should count as TWO properties added |
| 185 | + assert_eq!(object_change.props_added.len(), 2, |
| 186 | + "Expected 2 properties added, got {}: {:?}", |
| 187 | + object_change.props_added.len(), |
| 188 | + object_change.props_added); |
| 189 | +} |
| 190 | + |
0 commit comments