diff --git a/cpp/include/loot/database_interface.h b/cpp/include/loot/database_interface.h index fefc2aab..8ded7407 100644 --- a/cpp/include/loot/database_interface.h +++ b/cpp/include/loot/database_interface.h @@ -61,8 +61,7 @@ public: * The relative or absolute path to the masterlist file that should be * loaded. */ - virtual void LoadMasterlist( - const std::filesystem::path& masterlistPath) = 0; + virtual void LoadMasterlist(const std::filesystem::path& masterlistPath) = 0; /** * @brief Loads the masterlist and masterlist prelude from the paths @@ -141,9 +140,14 @@ public: /** * @brief Gets the Bash Tags that are listed in the loaded metadata lists. * @details Bash Tag suggestions can include Bash Tags not in this list. + * @param includeUserMetadata + * If true, any Bash Tag metadata present in the userlist is included + * in the returned metadata, otherwise the metadata returned only + * includes metadata from the masterlist. * @returns The Bash Tag names, which may include duplicates. */ - virtual std::vector GetKnownBashTags() const = 0; + virtual std::vector GetKnownBashTags( + bool includeUserMetadata = true) const = 0; /** * @brief Gets the Bash Tags that are listed in the loaded userlist. diff --git a/cpp/src/api/database.cpp b/cpp/src/api/database.cpp index 49b8e1e6..6ddf3b42 100644 --- a/cpp/src/api/database.cpp +++ b/cpp/src/api/database.cpp @@ -60,9 +60,11 @@ void Database::ClearConditionCache() { } } -std::vector Database::GetKnownBashTags() const { +std::vector Database::GetKnownBashTags( + bool includeUserMetadata) const { try { - return convert(database_->known_bash_tags()); + return convert( + database_->known_bash_tags(includeUserMetadata)); } catch (const ::rust::Error& e) { std::rethrow_exception(mapError(e)); } diff --git a/cpp/src/api/database.h b/cpp/src/api/database.h index df310d38..6e90a923 100644 --- a/cpp/src/api/database.h +++ b/cpp/src/api/database.h @@ -28,7 +28,8 @@ public: void ClearConditionCache() override; - std::vector GetKnownBashTags() const override; + std::vector GetKnownBashTags( + bool includeUserMetadata = true) const override; std::vector GetUserKnownBashTags() const override; diff --git a/cpp/src/database.rs b/cpp/src/database.rs index 21e5cf34..61190071 100644 --- a/cpp/src/database.rs +++ b/cpp/src/database.rs @@ -103,12 +103,15 @@ impl Database { Ok(()) } - pub fn known_bash_tags(&self) -> Result, VerboseError> { + pub fn known_bash_tags( + &self, + include_user_metadata: bool, + ) -> Result, VerboseError> { Ok(self .0 .read() .map_err(DatabaseLockPoisonError::from)? - .known_bash_tags()) + .known_bash_tags(to_merge_mode(include_user_metadata))) } pub fn user_known_bash_tags(&self) -> Result, VerboseError> { diff --git a/cpp/src/lib.rs b/cpp/src/lib.rs index 334def65..87f30a07 100644 --- a/cpp/src/lib.rs +++ b/cpp/src/lib.rs @@ -268,7 +268,7 @@ mod ffi { pub fn clear_condition_cache(&self) -> Result<()>; - pub fn known_bash_tags(&self) -> Result>; + pub fn known_bash_tags(&self, include_user_metadata: bool) -> Result>; pub fn user_known_bash_tags(&self) -> Result>; diff --git a/cpp/src/tests/api/interface/database_interface_test.h b/cpp/src/tests/api/interface/database_interface_test.h index 5a8cd9d1..2de83be8 100644 --- a/cpp/src/tests/api/interface/database_interface_test.h +++ b/cpp/src/tests/api/interface/database_interface_test.h @@ -485,6 +485,24 @@ TEST_P(DatabaseInterfaceTest, EXPECT_EQ(expectedTags, tags); } +TEST_P( + DatabaseInterfaceTest, + getKnownBashTagsShouldReturnAllBashTagsListedInLoadedMasterlistOnlyWhenParamIsFalse) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + + ASSERT_NO_THROW(handle_->GetDatabase().LoadMasterlist(masterlistPath)); + ASSERT_NO_THROW(handle_->GetDatabase().LoadUserlist(userlistPath_)); + + auto tags = handle_->GetDatabase().GetKnownBashTags(false); + + std::vector expectedTags({ + "Actors.ACBS", + "C.Climate", + }); + EXPECT_EQ(expectedTags, tags); +} + TEST_P(DatabaseInterfaceTest, getUserKnownBashTagsShouldReturnAllBashTagsListedInLoadedUserMetadata) { ASSERT_NO_THROW(GenerateMasterlist()); diff --git a/nodejs/src/database.rs b/nodejs/src/database.rs index 1d3e3993..90863fb5 100644 --- a/nodejs/src/database.rs +++ b/nodejs/src/database.rs @@ -139,12 +139,15 @@ impl Database { } #[napi] - pub fn known_bash_tags(&self) -> Result, VerboseError> { + pub fn known_bash_tags( + &self, + include_user_metadata: MergeMode, + ) -> Result, VerboseError> { Ok(self .0 .read() .map_err(DatabaseLockPoisonError::from)? - .known_bash_tags()) + .known_bash_tags(include_user_metadata.into())) } #[napi] diff --git a/python/src/database.rs b/python/src/database.rs index 05f87aad..b1d18939 100644 --- a/python/src/database.rs +++ b/python/src/database.rs @@ -107,12 +107,15 @@ impl Database { Ok(()) } - pub fn known_bash_tags(&self) -> Result, VerboseError> { + pub fn known_bash_tags( + &self, + include_user_metadata: bool, + ) -> Result, VerboseError> { Ok(self .0 .read() .map_err(DatabaseLockPoisonError::from)? - .known_bash_tags()) + .known_bash_tags(to_merge_mode(include_user_metadata))) } pub fn user_known_bash_tags(&self) -> Result, VerboseError> { diff --git a/src/database/mod.rs b/src/database/mod.rs index eb6659a9..b5d65407 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -166,9 +166,12 @@ impl Database { /// Gets the Bash Tags that are listed in the loaded metadata lists. /// /// Bash Tag suggestions can include Bash Tags not in this list. - pub fn known_bash_tags(&self) -> Vec { + pub fn known_bash_tags(&self, include_user_metadata: MergeMode) -> Vec { let mut tags = self.masterlist.bash_tags().to_vec(); - tags.extend_from_slice(self.userlist.bash_tags()); + + if include_user_metadata == MergeMode::WithUserMetadata { + tags.extend_from_slice(self.userlist.bash_tags()); + } tags } @@ -482,7 +485,12 @@ plugins: database.load_masterlist(&fixture.metadata_path).unwrap(); - assert_eq!(&["C.Climate"], database.known_bash_tags().as_slice()); + assert_eq!( + &["C.Climate"], + database + .known_bash_tags(MergeMode::WithUserMetadata) + .as_slice() + ); } #[test] @@ -494,7 +502,12 @@ plugins: .load_masterlist_with_prelude(&fixture.metadata_path, &fixture.prelude_path) .unwrap(); - assert_eq!(&["Actors.ACBS"], database.known_bash_tags().as_slice()); + assert_eq!( + &["Actors.ACBS"], + database + .known_bash_tags(MergeMode::WithUserMetadata) + .as_slice() + ); } #[test] @@ -504,7 +517,12 @@ plugins: database.load_userlist(&fixture.metadata_path).unwrap(); - assert_eq!(&["C.Climate"], database.known_bash_tags().as_slice()); + assert_eq!( + &["C.Climate"], + database + .known_bash_tags(MergeMode::WithUserMetadata) + .as_slice() + ); assert_eq!( &[ Group::default(), @@ -887,22 +905,50 @@ plugins: assert!(!database.evaluate(condition).unwrap()); } - #[test] - fn known_bash_tags_should_append_userlist_tags_to_masterlist_tags() { - let fixture = Fixture::new(GameType::Oblivion); - let mut database = fixture.database(); + mod known_bash_tags { + use super::*; - database.load_masterlist(&fixture.metadata_path).unwrap(); + #[test] + fn should_not_append_userlist_tags_to_masterlist_tags_if_merge_mode_is_without_user_metadata() + { + let fixture = Fixture::new(GameType::Oblivion); + let mut database = fixture.database(); - let userlist_path = fixture.inner.local_path.join("userlist.yaml"); - std::fs::write(&userlist_path, "bash_tags: [Relev, Delev]").unwrap(); + database.load_masterlist(&fixture.metadata_path).unwrap(); - database.load_userlist(&userlist_path).unwrap(); + let userlist_path = fixture.inner.local_path.join("userlist.yaml"); + std::fs::write(&userlist_path, "bash_tags: [Relev, Delev]").unwrap(); - assert_eq!( - vec!["C.Climate", "Relev", "Delev"], - database.known_bash_tags() - ); + database.load_userlist(&userlist_path).unwrap(); + + assert_eq!( + vec!["C.Climate"], + database.known_bash_tags(MergeMode::WithoutUserMetadata) + ); + } + + #[test] + fn should_append_unique_userlist_tags_to_masterlist_tags_if_merge_mode_is_with_user_metadata() + { + let fixture = Fixture::new(GameType::Oblivion); + let mut database = fixture.database(); + + database.load_masterlist(&fixture.metadata_path).unwrap(); + + let userlist_path = fixture.inner.local_path.join("userlist.yaml"); + std::fs::write( + &userlist_path, + "bash_tags: [C.Climate, Relev, Delev, Relev]", + ) + .unwrap(); + + database.load_userlist(&userlist_path).unwrap(); + + assert_eq!( + vec!["C.Climate", "C.Climate", "Relev", "Delev", "Relev"], + database.known_bash_tags(MergeMode::WithUserMetadata) + ); + } } #[test]