This commit is contained in:
Biedermann Steve 2024-05-10 13:30:27 +02:00
parent e16b92f526
commit 26ea87b295
3 changed files with 50 additions and 44 deletions

View File

@ -43,5 +43,5 @@ topics:
The tool must be able to scan text files for requirement IDs and create a summary of the test status of the defined requirements. The tool must be able to scan text files for requirement IDs and create a summary of the test status of the defined requirements.
The IDs must be in one of the following formats, where <ID> is a placeholder for the real id: The IDs must be in one of the following formats, where <ID> is a placeholder for the real id:
additional_info: additional_info:
- "<ID>: success" - "<ID>: passed"
- "<ID>: failed" - "<ID>: failed"

View File

@ -35,24 +35,17 @@ fn nl() -> String {
fn check_requirements( fn check_requirements(
test_results: &str, test_results: &str,
output: &mut Vec<String>, output: &mut IndexMap<String, bool>,
requirements: &IndexMap<String, Requirement>, requirements: &IndexMap<String, Requirement>,
allowed_requirements: &Regex, allowed_requirements: &Regex,
) { ) {
for (id, requirement) in requirements { for (id, _) in dbg!(requirements) {
if allowed_requirements.is_match(id) { if allowed_requirements.is_match(id) {
let status = if test_results.contains(&format!("{} succeeded", id.trim())) { if test_results.contains(&format!("{}: failed", id.trim())) {
":white_check_mark:" output.insert(id.trim().to_string(), false);
} else if test_results.contains(&format!("{} failed", id.trim())) { } else if test_results.contains(&format!("{}: passed", id.trim())) {
":x:" output.entry(id.trim().to_string()).or_insert(true);
} else {
":warning:"
}; };
output.push(format!(
"- _{}_ - {}: {status}",
id.trim(),
requirement.name
));
} }
} }
} }
@ -72,14 +65,14 @@ fn has_valid_topics(mut topics: Values<String, Topic>, allowed_requirements: &Re
} }
fn check_topics( fn check_topics(
test_results: &str, test_results: &[PathBuf],
output: &mut Vec<String>, output: &mut Vec<String>,
topics: &IndexMap<String, Topic>, topics: &IndexMap<String, Topic>,
allowed_requirements: &Regex, allowed_requirements: &Regex,
level: usize, level: usize,
) { ) -> anyhow::Result<()> {
if !has_valid_topics(topics.values(), allowed_requirements) { if !has_valid_topics(topics.values(), allowed_requirements) {
return; return Ok(());
} }
for (id, topic) in topics { for (id, topic) in topics {
if !has_valid_topics(topic.subtopics.values(), allowed_requirements) if !has_valid_topics(topic.subtopics.values(), allowed_requirements)
@ -93,15 +86,37 @@ fn check_topics(
id.trim(), id.trim(),
topic.name topic.name
)); ));
let mut test_status = IndexMap::new();
for test_result in test_results {
let test_result = std::fs::read_to_string(test_result)?;
if !topic.requirements.is_empty() {
check_requirements(
&test_result,
&mut test_status,
&topic.requirements,
allowed_requirements,
);
}
}
if !topic.requirements.is_empty() { if !topic.requirements.is_empty() {
check_requirements( for (id, req) in &topic.requirements {
test_results, let status = if let Some(status) = test_status.get(id) {
output, if *status {
&topic.requirements, ":white_check_mark:"
allowed_requirements, } else {
); ":x:"
}
} else {
":warning:"
};
output.push(format!("- _{}_ - {}: {status}", id.trim(), req.name));
}
output.push(nl()); output.push(nl());
} }
if !topic.subtopics.is_empty() { if !topic.subtopics.is_empty() {
check_topics( check_topics(
test_results, test_results,
@ -109,10 +124,11 @@ fn check_topics(
&topic.subtopics, &topic.subtopics,
allowed_requirements, allowed_requirements,
level + 1, level + 1,
); )?;
output.push(nl()); output.push(nl());
} }
} }
Ok(())
} }
fn add_requirements(output: &mut Vec<String>, requirements: &IndexMap<String, Requirement>) { fn add_requirements(output: &mut Vec<String>, requirements: &IndexMap<String, Requirement>) {
@ -171,12 +187,14 @@ enum Command {
allowed_requirements: String, allowed_requirements: String,
/// The path to the requirements file /// The path to the requirements file
requirements: PathBuf, requirements: PathBuf,
/// The path to the test output file /// The path to the test output files
test_results: PathBuf, #[arg(required=true, num_args=1..)]
test_results: Vec<PathBuf>,
}, },
} }
#[derive(Parser)] #[derive(Parser)]
#[command(version)]
struct Args { struct Args {
#[clap(subcommand)] #[clap(subcommand)]
command: Command, command: Command,
@ -297,10 +315,9 @@ fn main() -> anyhow::Result<()> {
test_results, test_results,
} => { } => {
let re = Regex::new(&allowed_requirements).unwrap(); let re = Regex::new(&allowed_requirements).unwrap();
let test_results = std::fs::read_to_string(test_results)?;
let project: Project = parse(&std::fs::read_to_string(requirements)?)?; let project: Project = parse(&std::fs::read_to_string(requirements)?)?;
let mut output = vec![format!("# Test Results - {}", project.name)]; let mut output = vec![format!("# Test Results - {}", project.name)];
check_topics(&test_results, &mut output, &project.topics, &re, 2); check_topics(&test_results, &mut output, &project.topics, &re, 2)?;
let output = output.join("\n"); let output = output.join("\n");
println!("{output}"); println!("{output}");

View File

@ -1,16 +1,5 @@
REQ-1.1.1 succeeded REQ-1.1: passed
REQ-1.2.1 succeeded REQ-1.2: passed
REQ-1.2.2 failed REQ-3.1: passed
REQ-2.1.1 succeeded REQ-3.2: passed
REQ-2.1.2 succeeded REQ-3.3: failed
REQ-2.1.3 failed
REQ-2.2.1 succeeded
REQ-2.2.2 succeeded
REQ-2.2.3 failed
REQ-3.1.1 succeeded
REQ-3.1.2 succeeded
REQ-3.1.3 failed
REQ-3.1.4 succeeded
REQ-3.2.1 succeeded
REQ-3.2.2 failed
REQ-3.2.3 succeeded