use std::path::Path;
use derive_builder::Builder;
use git_checks_core::impl_prelude::*;
use itertools::Itertools;
use rayon::prelude::*;
#[derive(Debug, Clone)]
pub enum ChangelogStyle {
Directory {
path: String,
extension: Option<String>,
},
File {
path: String,
},
Files {
paths: Vec<String>,
},
}
impl ChangelogStyle {
pub fn file<P>(path: P) -> Self
where
P: Into<String>,
{
ChangelogStyle::File {
path: path.into(),
}
}
pub fn directory<P>(path: P, ext: Option<String>) -> Self
where
P: Into<String>,
{
ChangelogStyle::Directory {
path: path.into(),
extension: ext,
}
}
pub fn files<P, I>(paths: I) -> Self
where
I: IntoIterator<Item = P>,
P: Into<String>,
{
ChangelogStyle::Files {
paths: paths.into_iter().map(Into::into).collect(),
}
}
fn describe(&self) -> String {
match *self {
ChangelogStyle::Directory {
ref path,
ref extension,
} => {
if let Some(ext) = extension.as_ref() {
format!("a file ending with `.{}` in `{}`", ext, path)
} else {
format!("a file in `{}`", path)
}
},
ChangelogStyle::File {
ref path,
} => format!("the `{}` file", path),
ChangelogStyle::Files {
ref paths,
} => format!("one of the `{}` files", paths.iter().format("`, `")),
}
}
fn applies(&self, diff_path: &Path) -> bool {
match *self {
ChangelogStyle::Directory {
ref path,
ref extension,
} => {
let ext_ok = extension.as_ref().map_or(true, |ext| {
diff_path
.extension()
.map_or(false, |diff_ext| diff_ext == (ext.as_ref() as &Path))
});
ext_ok && diff_path.starts_with(path)
},
ChangelogStyle::File {
ref path,
} => diff_path == (path.as_ref() as &Path),
ChangelogStyle::Files {
ref paths,
} => {
paths
.iter()
.any(|path| diff_path == (path.as_ref() as &Path))
},
}
}
#[allow(clippy::match_like_matches_macro)]
fn is_ok(&self, status: StatusChange) -> bool {
match *self {
ChangelogStyle::Directory {
..
} => {
match status {
StatusChange::Added
| StatusChange::Modified(_)
| StatusChange::Deleted => true,
_ => false,
}
},
ChangelogStyle::File {
..
}
| ChangelogStyle::Files {
..
} => {
match status {
StatusChange::Added
| StatusChange::Modified(_) => true,
_ => false,
}
},
}
}
}
#[derive(Builder, Debug, Clone)]
#[builder(field(private))]
pub struct Changelog {
style: ChangelogStyle,
#[builder(default = "false")]
required: bool,
}
impl Changelog {
pub fn builder() -> ChangelogBuilder {
ChangelogBuilder::default()
}
}
impl ContentCheck for Changelog {
fn name(&self) -> &str {
"changelog"
}
fn check(
&self,
_: &CheckGitContext,
content: &dyn Content,
) -> Result<CheckResult, Box<dyn Error>> {
let mut result = CheckResult::new();
let changelog_changes = content
.diffs()
.par_iter()
.filter(|diff| {
diff.old_blob != diff.new_blob
&& self.style.applies(diff.name.as_path())
&& self.style.is_ok(diff.status)
})
.count();
if changelog_changes == 0 {
if self.required {
result.add_error(format!(
"{}missing a changelog entry in {}.",
commit_prefix_str(content, "not allowed;"),
self.style.describe(),
));
} else {
result.add_warning(format!(
"{}please consider adding a changelog entry in {}.",
commit_prefix_str(content, "is missing a changelog entry;"),
self.style.describe(),
));
};
}
Ok(result)
}
}
#[cfg(feature = "config")]
pub(crate) mod config {
use git_checks_config::{register_checks, CommitCheckConfig, IntoCheck, TopicCheckConfig};
use serde::Deserialize;
#[cfg(test)]
use serde_json::json;
#[cfg(test)]
use crate::test;
use crate::Changelog;
use crate::ChangelogStyle;
#[derive(Deserialize, Debug)]
#[serde(tag = "style")]
pub enum ChangelogConfig {
#[serde(rename = "directory")]
#[doc(hidden)]
Directory {
path: String,
#[serde(default)]
extension: Option<String>,
required: Option<bool>,
},
#[serde(rename = "file")]
#[doc(hidden)]
File {
path: String,
required: Option<bool>,
},
#[serde(rename = "files")]
#[doc(hidden)]
Files {
paths: Vec<String>,
required: Option<bool>,
},
}
impl IntoCheck for ChangelogConfig {
type Check = Changelog;
fn into_check(self) -> Self::Check {
let (style, required) = match self {
ChangelogConfig::Directory {
path,
extension,
required,
} => (ChangelogStyle::directory(path, extension), required),
ChangelogConfig::File {
path,
required,
} => (ChangelogStyle::file(path), required),
ChangelogConfig::Files {
paths,
required,
} => (ChangelogStyle::files(paths), required),
};
let mut builder = Changelog::builder();
builder.style(style);
if let Some(required) = required {
builder.required(required);
}
builder
.build()
.expect("configuration mismatch for `Changelog`")
}
}
register_checks! {
ChangelogConfig {
"changelog" => CommitCheckConfig,
"changelog/topic" => TopicCheckConfig,
},
}
#[test]
fn test_changelog_config_empty() {
let json = json!({});
let err = serde_json::from_value::<ChangelogConfig>(json).unwrap_err();
test::check_missing_json_field(err, "style");
}
#[test]
fn test_changelog_config_directory_path_is_required() {
let json = json!({
"style": "directory",
});
let err = serde_json::from_value::<ChangelogConfig>(json).unwrap_err();
test::check_missing_json_field(err, "path");
}
#[test]
fn test_changelog_config_directory_minimum_fields() {
let exp_path = "path/to/directory";
let json = json!({
"style": "directory",
"path": exp_path,
});
let check: ChangelogConfig = serde_json::from_value(json).unwrap();
if let ChangelogConfig::Directory {
ref path,
ref extension,
required,
} = &check
{
assert_eq!(path, exp_path);
assert_eq!(extension, &None);
assert_eq!(required, &None);
} else {
panic!("did not create a directory config: {:?}", check);
}
let check = check.into_check();
assert!(!check.required);
if let ChangelogStyle::Directory {
path,
extension,
} = &check.style
{
assert_eq!(path, exp_path);
assert_eq!(extension, &None);
} else {
panic!("did not create a directory style: {:?}", check);
}
}
#[test]
fn test_changelog_config_directory_all_fields() {
let exp_path = "path/to/directory";
let exp_ext: String = "md".into();
let json = json!({
"style": "directory",
"path": exp_path,
"extension": exp_ext,
"required": true,
});
let check: ChangelogConfig = serde_json::from_value(json).unwrap();
if let ChangelogConfig::Directory {
ref path,
ref extension,
required,
} = &check
{
assert_eq!(path, exp_path);
assert_eq!(extension, &Some(exp_ext.clone()));
assert_eq!(required, &Some(true));
} else {
panic!("did not create a directory config: {:?}", check);
}
let check = check.into_check();
assert!(check.required);
if let ChangelogStyle::Directory {
path,
extension,
} = &check.style
{
assert_eq!(path, exp_path);
assert_eq!(extension, &Some(exp_ext));
} else {
panic!("did not create a directory style: {:?}", check);
}
}
#[test]
fn test_changelog_config_file_path_is_required() {
let json = json!({
"style": "file",
});
let err = serde_json::from_value::<ChangelogConfig>(json).unwrap_err();
test::check_missing_json_field(err, "path");
}
#[test]
fn test_changelog_config_file_minimum_fields() {
let exp_path = "path/to/changelog.file";
let json = json!({
"style": "file",
"path": exp_path,
});
let check: ChangelogConfig = serde_json::from_value(json).unwrap();
if let ChangelogConfig::File {
ref path,
required,
} = &check
{
assert_eq!(path, exp_path);
assert_eq!(required, &None);
} else {
panic!("did not create a file config: {:?}", check);
}
let check = check.into_check();
assert!(!check.required);
if let ChangelogStyle::File {
path,
} = &check.style
{
assert_eq!(path, exp_path);
} else {
panic!("did not create a file style: {:?}", check);
}
}
#[test]
fn test_changelog_config_file_all_fields() {
let exp_path = "path/to/changelog.file";
let json = json!({
"style": "file",
"path": exp_path,
"required": true,
});
let check: ChangelogConfig = serde_json::from_value(json).unwrap();
if let ChangelogConfig::File {
ref path,
required,
} = &check
{
assert_eq!(path, exp_path);
assert_eq!(required, &Some(true));
} else {
panic!("did not create a file config: {:?}", check);
}
let check = check.into_check();
assert!(check.required);
if let ChangelogStyle::File {
path,
} = &check.style
{
assert_eq!(path, exp_path);
} else {
panic!("did not create a file style: {:?}", check);
}
}
#[test]
fn test_changelog_config_files_paths_is_required() {
let json = json!({
"style": "files",
});
let err = serde_json::from_value::<ChangelogConfig>(json).unwrap_err();
test::check_missing_json_field(err, "paths");
}
#[test]
fn test_changelog_config_files_minimum_fields() {
let exp_path1 = "path/to/first/changelog.file";
let exp_path2 = "path/to/second/changelog.file";
let json = json!({
"style": "files",
"paths": &[exp_path1, exp_path2],
});
let check: ChangelogConfig = serde_json::from_value(json).unwrap();
if let ChangelogConfig::Files {
ref paths,
required,
} = &check
{
assert_eq!(paths, &[exp_path1, exp_path2]);
assert_eq!(required, &None);
} else {
panic!("did not create a files config: {:?}", check);
}
let check = check.into_check();
assert!(!check.required);
if let ChangelogStyle::Files {
paths,
} = &check.style
{
assert_eq!(paths, &[exp_path1, exp_path2]);
} else {
panic!("did not create a files style: {:?}", check);
}
}
#[test]
fn test_changelog_config_files_all_fields() {
let exp_path1 = "path/to/first/changelog.file";
let exp_path2 = "path/to/second/changelog.file";
let json = json!({
"style": "files",
"paths": &[exp_path1, exp_path2],
"required": true,
});
let check: ChangelogConfig = serde_json::from_value(json).unwrap();
if let ChangelogConfig::Files {
ref paths,
required,
} = &check
{
assert_eq!(paths, &[exp_path1, exp_path2]);
assert_eq!(required, &Some(true));
} else {
panic!("did not create a files config: {:?}", check);
}
let check = check.into_check();
assert!(check.required);
if let ChangelogStyle::Files {
paths,
} = &check.style
{
assert_eq!(paths, &[exp_path1, exp_path2]);
} else {
panic!("did not create a files style: {:?}", check);
}
}
#[test]
fn test_changelog_config_invalid() {
let json = json!({
"style": "invalid",
});
let err = serde_json::from_value::<ChangelogConfig>(json).unwrap_err();
assert!(!err.is_io());
assert!(!err.is_syntax());
assert!(err.is_data());
assert!(!err.is_eof());
let msg = format!("{}", err);
if msg != "unknown variant `invalid`, expected `directory` or `file`" {
println!(
"Error message doesn't match. Was a new style added? ({})",
msg,
);
}
}
}
#[cfg(test)]
mod tests {
use git_checks_core::{Check, TopicCheck};
use crate::builders::ChangelogBuilder;
use crate::test::*;
use crate::Changelog;
use crate::ChangelogStyle;
const CHANGELOG_DELETE: &str = "e86c0859ed36311c2ebce1ff50790eb21eabba78";
const CHANGELOG_MISSING: &str = "66953d52f3ec6f6e4d731e7f2f70dc4000ab13ae";
const CHANGELOG_MISSING_FIXED: &str = "a1020529e12fab5f1f7c87c60247d0068e0c9d8c";
const CHANGELOG_MISSING_FIXED_BAD_EXT: &str = "72c4a5ead2fcb5ce6017a391a1767294944c3e9c";
const CHANGELOG_MODE_CHANGE_BASE: &str = "254882cfbc4004a678d992818b49d08dd416528e";
const CHANGELOG_MODE_CHANGE: &str = "98644c64aee43d327383254e36eeda477c341938";
const FILE_CHANGELOG_INIT: &str = "3cd51c974845ff0c120e87a8e20ad5cf44798321";
const FILE_CHANGELOG_ADDED: &str = "34762d3ec96e2a302a30842ccbb5765c2b4a61d5";
const DIRECTORY_CHANGELOG_ADD: &str = "ff67b91112f4af4861528ac11b1797490ce18fc4";
const DIRECTORY_CHANGELOG_DELETE: &str = "114c724c1def28ecc96f10a8dab462879c80580a";
const DIRECTORY_CHANGELOG_MODIFY: &str = "f2719062d6c9e7c3835b397bd9553fb7b68cce5f";
const DIRECTORY_CHANGELOG_PREFIX: &str = "5f5442e33b6d0dfe01a14d98476d14e54c4d590e";
const DIRECTORY_CHANGELOG_BAD_EXT: &str = "93e235f10a76d58581f2d6056faa9d796156c3ea";
#[test]
fn test_changelog_builder_default() {
assert!(Changelog::builder().build().is_err());
}
#[test]
fn test_changelog_builder_minimum_fields() {
assert!(Changelog::builder()
.style(ChangelogStyle::file("changelog.md"))
.build()
.is_ok());
}
#[test]
fn test_changelog_name_commit() {
let check = Changelog::builder()
.style(ChangelogStyle::file("changelog.md"))
.build()
.unwrap();
assert_eq!(Check::name(&check), "changelog");
}
#[test]
fn test_changelog_name_topic() {
let check = Changelog::builder()
.style(ChangelogStyle::file("changelog.md"))
.build()
.unwrap();
assert_eq!(TopicCheck::name(&check), "changelog");
}
fn file_changelog() -> ChangelogBuilder {
let mut builder = Changelog::builder();
builder.style(ChangelogStyle::file("changelog.md"));
builder
}
fn files_changelog() -> ChangelogBuilder {
let mut builder = Changelog::builder();
builder.style(ChangelogStyle::files(
["changelog.md", "other.md"].iter().cloned(),
));
builder
}
fn directory_changelog() -> ChangelogBuilder {
let mut builder = Changelog::builder();
builder.style(ChangelogStyle::directory("changes", None));
builder
}
fn directory_changelog_ext() -> ChangelogBuilder {
let mut builder = Changelog::builder();
builder.style(ChangelogStyle::directory("changes", Some("md".into())));
builder
}
#[test]
fn test_changelog_file() {
let check = file_changelog().required(true).build().unwrap();
let result = run_check("test_changelog_file", CHANGELOG_MISSING, check);
test_result_errors(
result,
&[
"commit 66953d52f3ec6f6e4d731e7f2f70dc4000ab13ae not allowed; missing a changelog \
entry in the `changelog.md` file.",
],
);
}
#[test]
fn test_changelog_file_mode_change() {
let check = file_changelog().required(true).build().unwrap();
let conf = make_check_conf(&check);
let result = test_check_base(
"test_changelog_file_mode_change",
CHANGELOG_MODE_CHANGE,
CHANGELOG_MODE_CHANGE_BASE,
&conf,
);
test_result_errors(
result,
&[
"commit 98644c64aee43d327383254e36eeda477c341938 not allowed; missing a changelog \
entry in the `changelog.md` file.",
],
);
}
#[test]
fn test_changelog_file_init() {
let check = file_changelog().required(true).build().unwrap();
run_check_ok("test_changelog_file_init", FILE_CHANGELOG_INIT, check);
}
#[test]
fn test_changelog_file_ok() {
let check = file_changelog().required(true).build().unwrap();
run_check_ok("test_changelog_file_ok", FILE_CHANGELOG_ADDED, check);
}
#[test]
fn test_changelog_file_delete() {
let check = file_changelog().required(true).build().unwrap();
let result = run_check("test_changelog_file_delete", CHANGELOG_DELETE, check);
test_result_errors(
result,
&[
"commit e86c0859ed36311c2ebce1ff50790eb21eabba78 not allowed; missing a changelog \
entry in the `changelog.md` file.",
],
);
}
#[test]
fn test_changelog_files() {
let check = files_changelog().required(true).build().unwrap();
let result = run_check("test_changelog_files", CHANGELOG_MISSING, check);
test_result_errors(
result,
&[
"commit 66953d52f3ec6f6e4d731e7f2f70dc4000ab13ae not allowed; missing a changelog \
entry in one of the `changelog.md`, `other.md` files.",
],
);
}
#[test]
fn test_changelog_files_mode_change() {
let check = files_changelog().required(true).build().unwrap();
let conf = make_check_conf(&check);
let result = test_check_base(
"test_changelog_files_mode_change",
CHANGELOG_MODE_CHANGE,
CHANGELOG_MODE_CHANGE_BASE,
&conf,
);
test_result_errors(
result,
&[
"commit 98644c64aee43d327383254e36eeda477c341938 not allowed; missing a changelog \
entry in one of the `changelog.md`, `other.md` files.",
],
);
}
#[test]
fn test_changelog_files_init() {
let check = files_changelog().required(true).build().unwrap();
run_check_ok("test_changelog_files_init", FILE_CHANGELOG_INIT, check);
}
#[test]
fn test_changelog_files_ok() {
let check = files_changelog().required(true).build().unwrap();
run_check_ok("test_changelog_files_ok", FILE_CHANGELOG_ADDED, check);
}
#[test]
fn test_changelog_files_delete() {
let check = files_changelog().required(true).build().unwrap();
let result = run_check("test_changelog_files_delete", CHANGELOG_DELETE, check);
test_result_errors(
result,
&[
"commit e86c0859ed36311c2ebce1ff50790eb21eabba78 not allowed; missing a changelog \
entry in one of the `changelog.md`, `other.md` files.",
],
);
}
#[test]
fn test_changelog_directory() {
let check = directory_changelog().required(true).build().unwrap();
let result = run_check("test_changelog_directory", CHANGELOG_MISSING, check);
test_result_errors(
result,
&[
"commit 66953d52f3ec6f6e4d731e7f2f70dc4000ab13ae not allowed; missing a changelog \
entry in a file in `changes`.",
],
);
}
#[test]
fn test_changelog_directory_mode_change() {
let check = directory_changelog().required(true).build().unwrap();
let conf = make_check_conf(&check);
let result = test_check_base(
"test_changelog_directory_mode_change",
CHANGELOG_MODE_CHANGE,
CHANGELOG_MODE_CHANGE_BASE,
&conf,
);
test_result_errors(
result,
&[
"commit 98644c64aee43d327383254e36eeda477c341938 not allowed; missing a changelog \
entry in a file in `changes`.",
],
);
}
#[test]
fn test_changelog_directory_bad_extension() {
let check = directory_changelog_ext().required(true).build().unwrap();
let result = run_check(
"test_changelog_directory_bad_extension",
DIRECTORY_CHANGELOG_BAD_EXT,
check,
);
test_result_errors(
result,
&[
"commit 93e235f10a76d58581f2d6056faa9d796156c3ea not allowed; missing a changelog \
entry in a file ending with `.md` in `changes`.",
],
);
}
#[test]
fn test_changelog_directory_delete() {
let check = directory_changelog().required(true).build().unwrap();
let conf = make_check_conf(&check);
let result = test_check_base(
"test_changelog_directory_delete",
DIRECTORY_CHANGELOG_DELETE,
CHANGELOG_MISSING_FIXED_BAD_EXT,
&conf,
);
test_result_ok(result);
}
#[test]
fn test_changelog_directory_modify() {
let check = directory_changelog().required(true).build().unwrap();
let conf = make_check_conf(&check);
let result = test_check_base(
"test_changelog_directory_modify",
DIRECTORY_CHANGELOG_MODIFY,
CHANGELOG_MISSING_FIXED_BAD_EXT,
&conf,
);
test_result_ok(result);
}
#[test]
fn test_changelog_directory_prefix() {
let check = directory_changelog().required(true).build().unwrap();
let result = run_check(
"test_changelog_directory_prefix",
DIRECTORY_CHANGELOG_PREFIX,
check,
);
test_result_errors(
result,
&[
"commit 5f5442e33b6d0dfe01a14d98476d14e54c4d590e not allowed; missing a changelog \
entry in a file in `changes`.",
],
);
}
#[test]
fn test_changelog_directory_ok() {
let check = directory_changelog().required(true).build().unwrap();
run_check_ok(
"test_changelog_directory_ok",
DIRECTORY_CHANGELOG_ADD,
check,
);
}
#[test]
fn test_changelog_directory_ok_extension() {
let check = directory_changelog_ext().required(true).build().unwrap();
run_check_ok(
"test_changelog_directory_ok_extension",
DIRECTORY_CHANGELOG_ADD,
check,
);
}
#[test]
fn test_changelog_warning_file() {
let check = file_changelog().build().unwrap();
let result = run_check("test_changelog_warning_file", CHANGELOG_MISSING, check);
test_result_warnings(result, &[
"commit 66953d52f3ec6f6e4d731e7f2f70dc4000ab13ae is missing a changelog entry; please \
consider adding a changelog entry in the `changelog.md` file.",
]);
}
#[test]
fn test_changelog_warning_files() {
let check = files_changelog().build().unwrap();
let result = run_check("test_changelog_warning_files", CHANGELOG_MISSING, check);
test_result_warnings(result, &[
"commit 66953d52f3ec6f6e4d731e7f2f70dc4000ab13ae is missing a changelog entry; please \
consider adding a changelog entry in one of the `changelog.md`, `other.md` files.",
]);
}
#[test]
fn test_changelog_warning_directory() {
let check = directory_changelog().build().unwrap();
let result = run_check("test_changelog_warning_directory", CHANGELOG_MISSING, check);
test_result_warnings(result, &[
"commit 66953d52f3ec6f6e4d731e7f2f70dc4000ab13ae is missing a changelog entry; please \
consider adding a changelog entry in a file in `changes`.",
]);
}
#[test]
fn test_changelog_topic_file() {
let check = file_changelog().required(true).build().unwrap();
let result = run_topic_check("test_changelog_topic_file", CHANGELOG_MISSING, check);
test_result_errors(
result,
&["missing a changelog entry in the `changelog.md` file."],
);
}
#[test]
fn test_changelog_topic_file_warning() {
let check = file_changelog().build().unwrap();
let result = run_topic_check(
"test_changelog_topic_file_warning",
CHANGELOG_MISSING,
check,
);
test_result_warnings(
result,
&["please consider adding a changelog entry in the `changelog.md` file."],
);
}
#[test]
fn test_changelog_topic_files() {
let check = files_changelog().required(true).build().unwrap();
let result = run_topic_check("test_changelog_topic_files", CHANGELOG_MISSING, check);
test_result_errors(
result,
&["missing a changelog entry in one of the `changelog.md`, `other.md` files."],
);
}
#[test]
fn test_changelog_topic_files_warning() {
let check = files_changelog().build().unwrap();
let result = run_topic_check(
"test_changelog_topic_files_warning",
CHANGELOG_MISSING,
check,
);
test_result_warnings(result, &[
"please consider adding a changelog entry in one of the `changelog.md`, `other.md` files.",
]);
}
#[test]
fn test_changelog_topic_directory() {
let check = directory_changelog().required(true).build().unwrap();
let result = run_topic_check("test_changelog_topic_directory", CHANGELOG_MISSING, check);
test_result_errors(
result,
&["missing a changelog entry in a file in `changes`."],
);
}
#[test]
fn test_changelog_topic_directory_warning() {
let check = directory_changelog().build().unwrap();
let result = run_topic_check(
"test_changelog_topic_directory_warning",
CHANGELOG_MISSING,
check,
);
test_result_warnings(
result,
&["please consider adding a changelog entry in a file in `changes`."],
);
}
#[test]
fn test_changelog_topic_directory_bad_ext() {
let check = directory_changelog_ext().required(true).build().unwrap();
let result = run_topic_check(
"test_changelog_topic_directory_bad_ext",
CHANGELOG_MISSING_FIXED,
check,
);
test_result_errors(
result,
&["missing a changelog entry in a file ending with `.md` in `changes`."],
);
}
#[test]
fn test_changelog_topic_directory_warning_bad_ext() {
let check = directory_changelog_ext().build().unwrap();
let result = run_topic_check(
"test_changelog_topic_directory_warning_bad_ext",
CHANGELOG_MISSING_FIXED,
check,
);
test_result_warnings(result, &[
"please consider adding a changelog entry in a file ending with `.md` in `changes`.",
]);
}
#[test]
fn test_changelog_topic_fixed_file() {
let check = file_changelog().required(true).build().unwrap();
run_topic_check_ok(
"test_changelog_topic_fixed_file",
CHANGELOG_MISSING_FIXED,
check,
);
}
#[test]
fn test_changelog_topic_fixed_files() {
let check = files_changelog().required(true).build().unwrap();
run_topic_check_ok(
"test_changelog_topic_fixed_files",
CHANGELOG_MISSING_FIXED,
check,
);
}
#[test]
fn test_changelog_topic_fixed_directory() {
let check = directory_changelog().required(true).build().unwrap();
run_topic_check_ok(
"test_changelog_topic_fixed_directory",
CHANGELOG_MISSING_FIXED,
check,
);
}
#[test]
fn test_changelog_topic_fixed_directory_bad_ext() {
let check = directory_changelog().required(true).build().unwrap();
run_topic_check_ok(
"test_changelog_topic_fixed_directory_bad_ext",
CHANGELOG_MISSING_FIXED_BAD_EXT,
check,
);
}
}