diff --git a/benches/binary.rs b/benches/binary.rs index 9c86e7c..3f73c5f 100644 --- a/benches/binary.rs +++ b/benches/binary.rs @@ -6,7 +6,7 @@ use rand::rngs::SmallRng; use rand::seq::SliceRandom as _; use rand::{Rng, SeedableRng}; use test_results_parser::binary::*; -use test_results_parser::{Outcome, PropertiesValue, Testrun, ValidatedString}; +use test_results_parser::{Outcome, PropertiesValue, Testrun}; criterion_group!(benches, binary); criterion_main!(benches); @@ -175,15 +175,15 @@ fn create_random_testcases( let name = Alphanumeric.sample_string(rng, name_len); Testrun { - name: name.try_into().unwrap(), - classname: ValidatedString::default(), + name: name, + classname: String::new(), duration: Some(1.0), outcome: Outcome::Pass, - testsuite: ValidatedString::default(), + testsuite: String::new(), failure_message: None, filename: None, build_url: None, - computed_name: ValidatedString::default(), + computed_name: String::new(), properties: PropertiesValue(None), } }) diff --git a/src/binary/mod.rs b/src/binary/mod.rs index 8cc7287..7f43fbd 100644 --- a/src/binary/mod.rs +++ b/src/binary/mod.rs @@ -18,24 +18,21 @@ mod tests { use raw::CommitHash; use timestamps::DAY; - use crate::{ - testrun::{Outcome, PropertiesValue, Testrun}, - validated_string::ValidatedString, - }; + use crate::testrun::{Outcome, PropertiesValue, Testrun}; use super::*; fn test() -> Testrun { Testrun { - name: "abc".try_into().unwrap(), - classname: ValidatedString::default(), + name: "abc".to_string(), + classname: String::new(), duration: Some(1.0), outcome: Outcome::Pass, - testsuite: ValidatedString::default(), + testsuite: String::new(), failure_message: None, filename: None, build_url: None, - computed_name: ValidatedString::default(), + computed_name: String::new(), properties: PropertiesValue(None), } } @@ -64,7 +61,7 @@ mod tests { test.duration = Some(2.0); session.insert(&test); - test.name = "def".try_into().unwrap(); + test.name = "def".into(); test.outcome = Outcome::Skip; test.duration = Some(0.0); session.insert(&test); @@ -98,7 +95,7 @@ mod tests { let mut session = writer.start_session(0, CommitHash::default(), &[]); session.insert(&test); - test.testsuite = "some testsuite".try_into().unwrap(); + test.testsuite = "some testsuite".into(); session.insert(&test); let mut buf = vec![]; diff --git a/src/junit.rs b/src/junit.rs index dcd23e5..6520e5f 100644 --- a/src/junit.rs +++ b/src/junit.rs @@ -10,14 +10,11 @@ use quick_xml::reader::Reader; use crate::compute_name::{compute_name, unescape_str}; use crate::testrun::{check_testsuites_name, Framework, Outcome, PropertiesValue, Testrun}; -use crate::validated_string::ValidatedString; use crate::warning::WarningInfo; use thiserror::Error; #[derive(Error, Debug)] enum ParseAttrsError { - #[error("Limit of string is 1000 chars, for {0}, we got {1}")] - AttrTooLong(&'static str, usize), #[error("Error converting attribute {0} to UTF-8 string")] ConversionError(&'static str), #[error("Missing name attribute in testcase")] @@ -31,30 +28,19 @@ fn convert_attribute(attribute: Attribute) -> Result { Ok(String::from_utf8(bytes)?) } -fn extract_validated_string( - attribute: Attribute, - field_name: &'static str, -) -> Result { - let unvalidated_string = - convert_attribute(attribute).map_err(|_| ParseAttrsError::ConversionError(field_name))?; - let string_len = unvalidated_string.len(); - ValidatedString::from_string(unvalidated_string) - .map_err(|_| ParseAttrsError::AttrTooLong(field_name, string_len)) -} - struct TestcaseAttrs { - name: ValidatedString, + name: String, time: Option, - classname: Option, - file: Option, + classname: Option, + file: Option, } // originally from https://gist.github.com/scott-codecov/311c174ecc7de87f7d7c50371c6ef927#file-cobertura-rs-L18-L31 fn parse_testcase_attrs(attributes: Attributes) -> Result { - let mut name: Option = None; + let mut name: Option = None; let mut time: Option = None; - let mut classname: Option = None; - let mut file: Option = None; + let mut classname: Option = None; + let mut file: Option = None; for attribute in attributes { let attribute = attribute.map_err(|_| ParseAttrsError::ParseError)?; @@ -67,13 +53,22 @@ fn parse_testcase_attrs(attributes: Attributes) -> Result { - classname = Some(extract_validated_string(attribute, "classname")?); + classname = Some( + convert_attribute(attribute) + .map_err(|_| ParseAttrsError::ConversionError("classname"))?, + ); } b"name" => { - name = Some(extract_validated_string(attribute, "name")?); + name = Some( + convert_attribute(attribute) + .map_err(|_| ParseAttrsError::ConversionError("name"))?, + ); } b"file" => { - file = Some(extract_validated_string(attribute, "file")?); + file = Some( + convert_attribute(attribute) + .map_err(|_| ParseAttrsError::ConversionError("file"))?, + ); } _ => {} } @@ -104,7 +99,7 @@ fn get_attribute(e: &BytesStart, name: &str) -> Result> { fn populate( rel_attrs: TestcaseAttrs, - testsuite: ValidatedString, + testsuite: String, testsuite_time: Option<&str>, framework: Option, network: Option<&HashSet>, @@ -127,7 +122,7 @@ fn populate( failure_message: None, filename: file, build_url: None, - computed_name: ValidatedString::default(), + computed_name: String::new(), properties: PropertiesValue(None), }; @@ -139,8 +134,7 @@ fn populate( t.filename.as_deref(), network, ); - t.computed_name = ValidatedString::from_string(computed_name) - .context("Error converting computed name to ValidatedString")?; + t.computed_name = computed_name; Ok((t, framework)) } @@ -255,14 +249,9 @@ fn parse_property_element(e: &BytesStart, existing_properties: &mut PropertiesVa Ok(()) } -enum TestrunOrSkipped { - Testrun(Testrun), - Skipped, -} - fn handle_property_element( e: &BytesStart, - saved_testrun: &mut Option, + saved_testrun: &mut Option, buffer_position: u64, warnings: &mut Vec, ) -> Result<()> { @@ -270,19 +259,17 @@ fn handle_property_element( if saved_testrun.is_none() { return Ok(()); } - let saved = saved_testrun + let testrun = saved_testrun .as_mut() .context("Error accessing saved testrun")?; - if let TestrunOrSkipped::Testrun(testrun) = saved { - if let Err(e) = parse_property_element(e, &mut testrun.properties) { - if !e.is::() { - warnings.push(WarningInfo::new( - format!("Error parsing `property` element: {}", e), - buffer_position, - )); - } + if let Err(e) = parse_property_element(e, &mut testrun.properties) { + if !e.is::() { + warnings.push(WarningInfo::new( + format!("Error parsing `property` element: {}", e), + buffer_position, + )); } - }; + } Ok(()) } @@ -291,7 +278,7 @@ pub fn use_reader( network: Option<&HashSet>, ) -> PyResult<(Option, Vec, Vec)> { let mut testruns: Vec = Vec::new(); - let mut saved_testrun: Option = None; + let mut saved_testrun: Option = None; let mut in_failure: bool = false; let mut in_error: bool = false; @@ -303,7 +290,7 @@ pub fn use_reader( // every time we come across a testsuite element we update this vector: // if the testsuite element contains the time attribute append its value to this vec // else append a clone of the last value in the vec - let mut testsuite_names: Vec> = vec![]; + let mut testsuite_names: Vec> = vec![]; let mut testsuite_times: Vec> = vec![]; let mut buf = Vec::new(); @@ -331,78 +318,47 @@ pub fn use_reader( framework, network, )?; - saved_testrun = Some(TestrunOrSkipped::Testrun(testrun)); + saved_testrun = Some(testrun); framework = parsed_framework; } - Err(error) => match error { - ParseAttrsError::AttrTooLong(_, _) => { - warnings.push(WarningInfo::new( - format!("Warning while parsing testcase attributes: {}", error), - reader.buffer_position() - e.len() as u64, - )); - saved_testrun = Some(TestrunOrSkipped::Skipped); - } - _ => { - Err(anyhow::anyhow!( - "Error parsing testcase attributes: {}", - error - ))?; - } - }, + Err(error) => { + Err(anyhow::anyhow!( + "Error parsing testcase attributes: {}", + error + ))?; + } } } b"skipped" => { - let saved = saved_testrun + let testrun = saved_testrun .as_mut() - .context("Error accessing saved testrun")?; - match saved { - TestrunOrSkipped::Testrun(testrun) => { - testrun.outcome = Outcome::Skip; - } - TestrunOrSkipped::Skipped => {} - } + .context("Encountered tag outside of ")?; + testrun.outcome = Outcome::Skip; } b"error" => { - let saved = saved_testrun + let testrun = saved_testrun .as_mut() - .context("Error accessing saved testrun")?; - match saved { - TestrunOrSkipped::Testrun(testrun) => { - testrun.outcome = Outcome::Error; + .context("Encountered tag outside of ")?; + testrun.outcome = Outcome::Error; - testrun.failure_message = get_attribute(&e, "message")? - .map(|failure_message| unescape_str(&failure_message).into()); - } - TestrunOrSkipped::Skipped => {} - } + testrun.failure_message = get_attribute(&e, "message")? + .map(|failure_message| unescape_str(&failure_message).into()); in_error = true; } b"failure" => { - let saved = saved_testrun + let testrun = saved_testrun .as_mut() - .context("Error accessing saved testrun")?; - match saved { - TestrunOrSkipped::Testrun(testrun) => { - testrun.outcome = Outcome::Failure; + .context("Encountered tag outside of ")?; + testrun.outcome = Outcome::Failure; - testrun.failure_message = get_attribute(&e, "message")? - .map(|failure_message| unescape_str(&failure_message).into()); - } - TestrunOrSkipped::Skipped => {} - } + testrun.failure_message = get_attribute(&e, "message")? + .map(|failure_message| unescape_str(&failure_message).into()); in_failure = true; } b"testsuite" => { - testsuite_names.push( - get_attribute(&e, "name")? - .map(|s| { - ValidatedString::from_string(s) - .context("Error converting testsuite name to ValidatedString") - }) - .transpose()?, - ); + testsuite_names.push(get_attribute(&e, "name")?); testsuite_times.push(get_attribute(&e, "time")?); } b"testsuites" => { @@ -419,12 +375,12 @@ pub fn use_reader( }, Event::End(e) => match e.name().as_ref() { b"testcase" => { - let saved = saved_testrun.take().context( - "Met testcase closing tag without first meeting testcase opening tag", - )?; - match saved { - TestrunOrSkipped::Testrun(testrun) => testruns.push(testrun), - TestrunOrSkipped::Skipped => {} + if let Some(testrun) = saved_testrun.take() { + testruns.push(testrun); + } else { + Err(anyhow::anyhow!( + "Encountered closing tag without corresponding opening tag" + ))?; } } b"failure" => in_failure = false, @@ -454,58 +410,37 @@ pub fn use_reader( testruns.push(testrun); framework = parsed_framework; } - Err(error) => match error { - ParseAttrsError::AttrTooLong(_, _) => { - warnings.push(WarningInfo::new( - format!("Warning while parsing testcase attributes: {}", error), - reader.buffer_position() - e.len() as u64, - )); - } - _ => Err(anyhow::anyhow!( + Err(error) => { + Err(anyhow::anyhow!( "Error parsing testcase attributes: {}", error - ))?, - }, + ))?; + } } } b"failure" => { - let saved = saved_testrun + let testrun = saved_testrun .as_mut() - .context("Error accessing saved testrun")?; - match saved { - TestrunOrSkipped::Testrun(testrun) => { - testrun.outcome = Outcome::Failure; + .context("Encountered tag outside of ")?; + testrun.outcome = Outcome::Failure; - testrun.failure_message = get_attribute(&e, "message")? - .map(|failure_message| unescape_str(&failure_message).into()); - } - TestrunOrSkipped::Skipped => {} - } + testrun.failure_message = get_attribute(&e, "message")? + .map(|failure_message| unescape_str(&failure_message).into()); } b"skipped" => { - let saved = saved_testrun + let testrun = saved_testrun .as_mut() - .context("Error accessing saved testrun")?; - match saved { - TestrunOrSkipped::Testrun(testrun) => { - testrun.outcome = Outcome::Skip; - } - TestrunOrSkipped::Skipped => {} - } + .context("Encountered tag outside of ")?; + testrun.outcome = Outcome::Skip; } b"error" => { - let saved = saved_testrun + let testrun = saved_testrun .as_mut() - .context("Error accessing saved testrun")?; - match saved { - TestrunOrSkipped::Testrun(testrun) => { - testrun.outcome = Outcome::Error; + .context("Encountered tag outside of ")?; + testrun.outcome = Outcome::Error; - testrun.failure_message = get_attribute(&e, "message")? - .map(|failure_message| unescape_str(&failure_message).into()); - } - TestrunOrSkipped::Skipped => {} - } + testrun.failure_message = get_attribute(&e, "message")? + .map(|failure_message| unescape_str(&failure_message).into()); } b"property" => handle_property_element( &e, @@ -517,19 +452,12 @@ pub fn use_reader( }, Event::Text(mut xml_failure_message) => { if in_failure || in_error { - let saved = saved_testrun - .as_mut() - .context("Error accessing saved testrun")?; - match saved { - TestrunOrSkipped::Testrun(testrun) => { - xml_failure_message.inplace_trim_end(); - xml_failure_message.inplace_trim_start(); - - testrun.failure_message = Some( - unescape_str(std::str::from_utf8(&xml_failure_message)?).into(), - ); - } - TestrunOrSkipped::Skipped => {} + if let Some(testrun) = saved_testrun.as_mut() { + xml_failure_message.inplace_trim_end(); + xml_failure_message.inplace_trim_start(); + + testrun.failure_message = + Some(unescape_str(std::str::from_utf8(&xml_failure_message)?).into()); } } } diff --git a/src/lib.rs b/src/lib.rs index 68ffdfe..c49a3e8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,11 +7,9 @@ mod failure_message; mod junit; mod raw_upload; mod testrun; -mod validated_string; mod warning; pub use testrun::{Outcome, PropertiesValue, Testrun}; -pub use validated_string::ValidatedString; pyo3::create_exception!(test_results_parser, ComputeNameError, PyException); /// A Python module implemented in Rust. diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@ctest.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@ctest.xml.snap index e882aac..195c32a 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@ctest.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@ctest.xml.snap @@ -1,6 +1,5 @@ --- source: src/raw_upload.rs -assertion_line: 173 expression: results input_file: tests/ctest.xml --- diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@empty_failure.junit.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@empty_failure.junit.xml.snap index c7048d2..2d08646 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@empty_failure.junit.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@empty_failure.junit.xml.snap @@ -1,6 +1,5 @@ --- source: src/raw_upload.rs -assertion_line: 173 expression: results input_file: tests/empty_failure.junit.xml --- diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@jest-junit.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@jest-junit.xml.snap index b34a90f..ab15fac 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@jest-junit.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@jest-junit.xml.snap @@ -1,6 +1,5 @@ --- source: src/raw_upload.rs -assertion_line: 173 expression: results input_file: tests/jest-junit.xml --- diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@junit-nested-testsuite.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@junit-nested-testsuite.xml.snap index 59424c8..569db9a 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@junit-nested-testsuite.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@junit-nested-testsuite.xml.snap @@ -1,6 +1,5 @@ --- source: src/raw_upload.rs -assertion_line: 173 expression: results input_file: tests/junit-nested-testsuite.xml --- diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@junit-no-testcase-timestamp.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@junit-no-testcase-timestamp.xml.snap index 627f1b8..30b742e 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@junit-no-testcase-timestamp.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@junit-no-testcase-timestamp.xml.snap @@ -1,6 +1,5 @@ --- source: src/raw_upload.rs -assertion_line: 173 expression: results input_file: tests/junit-no-testcase-timestamp.xml --- diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@junit.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@junit.xml.snap index 339213c..ebd9cb2 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@junit.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@junit.xml.snap @@ -1,6 +1,5 @@ --- source: src/raw_upload.rs -assertion_line: 173 expression: results input_file: tests/junit.xml --- diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@no-testsuite-name.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@no-testsuite-name.xml.snap index c0e792c..40d8171 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@no-testsuite-name.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@no-testsuite-name.xml.snap @@ -1,6 +1,5 @@ --- source: src/raw_upload.rs -assertion_line: 173 expression: results input_file: tests/no-testsuite-name.xml --- diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@no-time.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@no-time.xml.snap index 24d0cf3..c169813 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@no-time.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@no-time.xml.snap @@ -1,6 +1,5 @@ --- source: src/raw_upload.rs -assertion_line: 173 expression: results input_file: tests/no-time.xml --- diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@phpunit.junit.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@phpunit.junit.xml.snap index b06da29..ff06fce 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@phpunit.junit.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@phpunit.junit.xml.snap @@ -1,6 +1,5 @@ --- source: src/raw_upload.rs -assertion_line: 173 expression: results input_file: tests/phpunit.junit.xml --- diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@skip-error.junit.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@skip-error.junit.xml.snap index cebf8c3..55589fb 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@skip-error.junit.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@skip-error.junit.xml.snap @@ -1,6 +1,5 @@ --- source: src/raw_upload.rs -assertion_line: 173 expression: results input_file: tests/skip-error.junit.xml --- diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@vitest-junit.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@vitest-junit.xml.snap index b31c82b..c9f1393 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@vitest-junit.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@vitest-junit.xml.snap @@ -1,6 +1,5 @@ --- source: src/raw_upload.rs -assertion_line: 173 expression: results input_file: tests/vitest-junit.xml --- diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@warnings-junit.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@warnings-junit.xml.snap index 91d9086..3d56c6f 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@warnings-junit.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@warnings-junit.xml.snap @@ -4,7 +4,25 @@ expression: results input_file: tests/warnings-junit.xml --- - framework: Jest - testruns: [] - warnings: - - "Warning while parsing testcase attributes: Limit of string is 1000 chars, for classname, we got 2010 at 5:6 in warnings-junit.xml" - - "Warning while parsing testcase attributes: Limit of string is 1000 chars, for name, we got 2004 at 9:6 in warnings-junit.xml" + testruns: + - name: Title when rendered renders pull title + classname: Really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really long class name + duration: 0.036 + outcome: Pass + testsuite: Title + failure_message: ~ + filename: ~ + build_url: ~ + computed_name: Title when rendered renders pull title + properties: ~ + - name: Really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really long name + classname: class names + duration: 0.036 + outcome: Pass + testsuite: Title + failure_message: ~ + filename: ~ + build_url: ~ + computed_name: Really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really long name + properties: ~ + warnings: [] diff --git a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@with-eval-properties-junit.xml.snap b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@with-eval-properties-junit.xml.snap index f92dc6f..02a66cb 100644 --- a/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@with-eval-properties-junit.xml.snap +++ b/src/snapshots/test_results_parser__raw_upload__tests__parse_raw_upload_success@with-eval-properties-junit.xml.snap @@ -1,6 +1,5 @@ --- source: src/raw_upload.rs -assertion_line: 173 expression: results input_file: tests/with-eval-properties-junit.xml --- diff --git a/src/testrun.rs b/src/testrun.rs index 7070da7..d4a936b 100644 --- a/src/testrun.rs +++ b/src/testrun.rs @@ -4,8 +4,6 @@ use pyo3::{PyAny, PyResult}; use serde::Serialize; use serde_json::Value; -use crate::validated_string::ValidatedString; - static FRAMEWORKS: [(&str, Framework); 4] = [ ("pytest", Framework::Pytest), ("vitest", Framework::Vitest), @@ -154,23 +152,23 @@ impl<'py> FromPyObject<'py> for PropertiesValue { #[derive(IntoPyObject, FromPyObject, Clone, Debug, Serialize, PartialEq)] pub struct Testrun { #[pyo3(item)] - pub name: ValidatedString, + pub name: String, #[pyo3(item)] - pub classname: ValidatedString, + pub classname: String, #[pyo3(item)] pub duration: Option, #[pyo3(item)] pub outcome: Outcome, #[pyo3(item)] - pub testsuite: ValidatedString, + pub testsuite: String, #[pyo3(item)] pub failure_message: Option, #[pyo3(item)] - pub filename: Option, + pub filename: Option, #[pyo3(item)] pub build_url: Option, #[pyo3(item)] - pub computed_name: ValidatedString, + pub computed_name: String, #[pyo3(item)] pub properties: PropertiesValue, } @@ -237,15 +235,15 @@ mod tests { #[test] fn test_detect_framework_testsuite_name() { let t = Testrun { - classname: ValidatedString::default(), - name: ValidatedString::default(), + classname: String::new(), + name: String::new(), duration: None, outcome: Outcome::Pass, - testsuite: "pytest".try_into().unwrap(), + testsuite: "pytest".to_string(), failure_message: None, filename: None, build_url: None, - computed_name: ValidatedString::default(), + computed_name: String::new(), properties: PropertiesValue(None), }; assert_eq!(t.framework(), Some(Framework::Pytest)) @@ -254,15 +252,15 @@ mod tests { #[test] fn test_detect_framework_filenames() { let t = Testrun { - classname: ValidatedString::default(), - name: ValidatedString::default(), + classname: String::new(), + name: String::new(), duration: None, outcome: Outcome::Pass, - testsuite: ValidatedString::default(), + testsuite: String::new(), failure_message: None, - filename: Some(".py".try_into().unwrap()), + filename: Some(".py".to_string()), build_url: None, - computed_name: ValidatedString::default(), + computed_name: String::new(), properties: PropertiesValue(None), }; assert_eq!(t.framework(), Some(Framework::Pytest)) @@ -271,15 +269,15 @@ mod tests { #[test] fn test_detect_framework_example_classname() { let t = Testrun { - classname: ".py".try_into().unwrap(), - name: ValidatedString::default(), + classname: ".py".to_string(), + name: String::new(), duration: None, outcome: Outcome::Pass, - testsuite: ValidatedString::default(), + testsuite: String::new(), failure_message: None, filename: None, build_url: None, - computed_name: ValidatedString::default(), + computed_name: String::new(), properties: PropertiesValue(None), }; assert_eq!(t.framework(), Some(Framework::Pytest)) @@ -288,15 +286,15 @@ mod tests { #[test] fn test_detect_framework_example_name() { let t = Testrun { - classname: ValidatedString::default(), - name: ".py".try_into().unwrap(), + classname: String::new(), + name: ".py".to_string(), duration: None, outcome: Outcome::Pass, - testsuite: ValidatedString::default(), + testsuite: String::new(), failure_message: None, filename: None, build_url: None, - computed_name: ValidatedString::default(), + computed_name: String::new(), properties: PropertiesValue(None), }; assert_eq!(t.framework(), Some(Framework::Pytest)) @@ -305,15 +303,15 @@ mod tests { #[test] fn test_detect_framework_failure_messages() { let t = Testrun { - classname: ValidatedString::default(), - name: ValidatedString::default(), + classname: String::new(), + name: String::new(), duration: None, outcome: Outcome::Pass, - testsuite: ValidatedString::default(), + testsuite: String::new(), failure_message: Some(".py".to_string()), filename: None, build_url: None, - computed_name: ValidatedString::default(), + computed_name: String::new(), properties: PropertiesValue(None), }; assert_eq!(t.framework(), Some(Framework::Pytest)) @@ -322,15 +320,15 @@ mod tests { #[test] fn test_detect_build_url() { let t = Testrun { - classname: ValidatedString::default(), - name: ValidatedString::default(), + classname: String::new(), + name: String::new(), duration: None, outcome: Outcome::Pass, - testsuite: ValidatedString::default(), + testsuite: String::new(), failure_message: Some(".py".to_string()), filename: None, build_url: Some("https://example.com/build_url".to_string()), - computed_name: ValidatedString::default(), + computed_name: String::new(), properties: PropertiesValue(None), }; assert_eq!(t.framework(), Some(Framework::Pytest)) diff --git a/src/validated_string.rs b/src/validated_string.rs deleted file mode 100644 index 17cf34b..0000000 --- a/src/validated_string.rs +++ /dev/null @@ -1,49 +0,0 @@ -use std::ops::Deref; - -use anyhow::{Context, Result}; -use pyo3::{FromPyObject, IntoPyObject}; -use serde::{Deserialize, Serialize}; - -// String that is validated to be less than 1000 characters - -#[derive( - Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, FromPyObject, IntoPyObject, -)] -#[serde(transparent)] -#[pyo3(transparent)] -pub struct ValidatedString { - value: String, -} - -impl ValidatedString { - pub fn from_string(value: String) -> Result { - if value.len() > 1000 { - anyhow::bail!("string is too long"); - } - Ok(Self { value }) - } -} - -impl Deref for ValidatedString { - type Target = str; - - fn deref(&self) -> &Self::Target { - &self.value - } -} - -impl TryFrom for ValidatedString { - type Error = anyhow::Error; - - fn try_from(value: String) -> Result { - Self::from_string(value).context("Error converting String to ValidatedString") - } -} - -impl TryFrom<&str> for ValidatedString { - type Error = anyhow::Error; - - fn try_from(value: &str) -> Result { - Self::from_string(value.to_string()).context("Error converting &str to ValidatedString") - } -}