use crate::test_parser::{ParsedTest, TestStatus};
use crate::{ParsedTestSuite, TestParser};
use serde;
use serde::{Deserialize, Serialize};
use serde_xml_rs::Error;
#[derive(Deserialize, Serialize, Debug, PartialEq)]
#[serde(rename = "testsuite")]
pub(crate) struct TestSuite {
pub(crate) name: String,
pub(crate) tests: usize,
pub(crate) skipped: usize,
pub(crate) failures: usize,
pub(crate) errors: usize,
pub(crate) timestamp: String,
pub(crate) hostname: String,
pub(crate) time: f64,
#[serde(rename = "testcase")]
pub(crate) test_cases: Option<Vec<TestCase>>,
#[serde(rename = "system-out")]
pub(crate) std_out: Option<String>,
#[serde(rename = "system-err")]
pub(crate) std_err: Option<String>,
}
#[derive(Deserialize, Serialize, Debug, PartialEq)]
#[serde(rename = "testcase")]
pub(crate) struct TestCase {
pub(crate) name: String,
pub(crate) classname: String,
pub(crate) time: f64,
pub(crate) failure: Option<Failure>,
}
#[derive(Deserialize, Serialize, Debug, PartialEq)]
#[serde(rename = "failure")]
pub(crate) struct Failure {
pub(crate) message: String,
#[serde(rename = "$value")]
pub(crate) content: Option<String>,
}
pub(crate) struct JUnitTestParser {}
impl JUnitTestParser {
pub(crate) fn new() -> Self {
Self {}
}
}
impl TestParser for JUnitTestParser {
type Error = Error;
fn multi_line(&self) -> bool {
false
}
fn parse(&mut self, text: &str) -> Result<Option<ParsedTestSuite>, Error> {
let test_suite: TestSuite = serde_xml_rs::from_str(text)?;
let tests = test_suite
.test_cases
.map(|v| {
v.iter()
.map(|e| ParsedTest {
full_name: e.name.clone(),
name: e.name.clone(),
module: Some(e.classname.clone()),
exec_time: Some(e.time),
status: e
.failure
.as_ref()
.map(|_| TestStatus::Failed)
.unwrap_or(TestStatus::Ok),
std_out: e.failure.as_ref().map(|e| e.content.clone()).flatten(),
})
.collect::<Vec<_>>()
})
.unwrap_or(vec![]);
Ok(Some(ParsedTestSuite {
suite_name: test_suite.name,
test_count: test_suite.tests,
passed: test_suite.tests - test_suite.failures,
failed: test_suite.failures,
errors: test_suite.errors,
allowed_fail: 0,
ignored: test_suite.skipped,
measured: 0,
filtered_out: 0,
exec_time: test_suite.time,
tests,
}))
}
fn reset(&mut self) {}
}