-
-
Notifications
You must be signed in to change notification settings - Fork 3
No default features #430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
No default features #430
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,14 +11,20 @@ categories = ["encoding", "development-tools"] | |
edition = "2021" | ||
rust-version = "1.70" | ||
|
||
[features] | ||
default = ["timestamps", "uuids", "strip-ansi"] | ||
timestamps = ["dep:chrono"] | ||
uuids = ["dep:uuid", "dep:newtype-uuid"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's call this feature |
||
strip-ansi = ["dep:strip-ansi-escapes"] | ||
|
||
[dependencies] | ||
chrono = { version = "0.4.41", default-features = false, features = ["std"] } | ||
chrono = { version = "0.4.41", default-features = false, features = ["std"], optional = true } | ||
indexmap = "2.7.1" | ||
quick-xml = "0.38.1" | ||
newtype-uuid = "1.2.4" | ||
newtype-uuid = { version = "1.2.4", optional = true } | ||
thiserror = "2.0.12" | ||
strip-ansi-escapes = "0.2.1" | ||
uuid = "1.17.0" | ||
strip-ansi-escapes = { version = "0.2.1", optional = true } | ||
uuid = { version = "1.17.0", optional = true } | ||
|
||
[dev-dependencies] | ||
goldenfile = "1.7.3" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,15 +2,20 @@ | |
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
|
||
use crate::{serialize::serialize_report, SerializeError}; | ||
#[cfg(feature = "timestamps")] | ||
use chrono::{DateTime, FixedOffset}; | ||
use indexmap::map::IndexMap; | ||
#[cfg(feature = "uuids")] | ||
use newtype_uuid::{GenericUuid, TypedUuid, TypedUuidKind, TypedUuidTag}; | ||
use std::{borrow::Borrow, hash::Hash, io, iter, ops::Deref, time::Duration}; | ||
#[cfg(feature = "uuids")] | ||
use uuid::Uuid; | ||
|
||
/// A tag indicating the kind of report. | ||
#[cfg(feature = "uuids")] | ||
pub enum ReportKind {} | ||
|
||
#[cfg(feature = "uuids")] | ||
impl TypedUuidKind for ReportKind { | ||
fn tag() -> TypedUuidTag { | ||
const TAG: TypedUuidTag = TypedUuidTag::new("quick-junit-report"); | ||
|
@@ -19,6 +24,7 @@ impl TypedUuidKind for ReportKind { | |
} | ||
|
||
/// A unique identifier associated with a report. | ||
#[cfg(feature = "uuids")] | ||
pub type ReportUuid = TypedUuid<ReportKind>; | ||
|
||
/// The root element of a JUnit report. | ||
|
@@ -30,11 +36,13 @@ pub struct Report { | |
/// A unique identifier associated with this report. | ||
/// | ||
/// This is an extension to the spec that's used by nextest. | ||
#[cfg(feature = "uuids")] | ||
pub uuid: Option<ReportUuid>, | ||
|
||
/// The time at which the first test in this report began execution. | ||
/// | ||
/// This is not part of the JUnit spec, but may be useful for some tools. | ||
#[cfg(feature = "timestamps")] | ||
pub timestamp: Option<DateTime<FixedOffset>>, | ||
|
||
/// The overall time taken by the test suite. | ||
|
@@ -60,7 +68,9 @@ impl Report { | |
pub fn new(name: impl Into<XmlString>) -> Self { | ||
Self { | ||
name: name.into(), | ||
#[cfg(feature = "uuids")] | ||
uuid: None, | ||
#[cfg(feature = "timestamps")] | ||
timestamp: None, | ||
time: None, | ||
tests: 0, | ||
|
@@ -73,6 +83,7 @@ impl Report { | |
/// Sets a unique ID for this `Report`. | ||
/// | ||
/// This is an extension that's used by nextest. | ||
#[cfg(feature = "uuids")] | ||
pub fn set_report_uuid(&mut self, uuid: ReportUuid) -> &mut Self { | ||
self.uuid = Some(uuid); | ||
self | ||
|
@@ -81,12 +92,14 @@ impl Report { | |
/// Sets a unique ID for this `Report` from an untyped [`Uuid`]. | ||
/// | ||
/// This is an extension that's used by nextest. | ||
#[cfg(feature = "uuids")] | ||
pub fn set_uuid(&mut self, uuid: Uuid) -> &mut Self { | ||
self.uuid = Some(ReportUuid::from_untyped_uuid(uuid)); | ||
self | ||
} | ||
|
||
/// Sets the start timestamp for the report. | ||
#[cfg(feature = "timestamps")] | ||
pub fn set_timestamp(&mut self, timestamp: impl Into<DateTime<FixedOffset>>) -> &mut Self { | ||
self.timestamp = Some(timestamp.into()); | ||
self | ||
|
@@ -165,6 +178,7 @@ pub struct TestSuite { | |
pub failures: usize, | ||
|
||
/// The time at which the TestSuite began execution. | ||
#[cfg(feature = "timestamps")] | ||
pub timestamp: Option<DateTime<FixedOffset>>, | ||
|
||
/// The overall time taken by the TestSuite. | ||
|
@@ -192,6 +206,7 @@ impl TestSuite { | |
Self { | ||
name: name.into(), | ||
time: None, | ||
#[cfg(feature = "timestamps")] | ||
timestamp: None, | ||
tests: 0, | ||
disabled: 0, | ||
|
@@ -206,6 +221,7 @@ impl TestSuite { | |
} | ||
|
||
/// Sets the start timestamp for the TestSuite. | ||
#[cfg(feature = "timestamps")] | ||
pub fn set_timestamp(&mut self, timestamp: impl Into<DateTime<FixedOffset>>) -> &mut Self { | ||
self.timestamp = Some(timestamp.into()); | ||
self | ||
|
@@ -309,6 +325,7 @@ pub struct TestCase { | |
/// The time at which this test case began execution. | ||
/// | ||
/// This is not part of the JUnit spec, but may be useful for some tools. | ||
#[cfg(feature = "timestamps")] | ||
pub timestamp: Option<DateTime<FixedOffset>>, | ||
|
||
/// The time it took to execute this test case. | ||
|
@@ -337,6 +354,7 @@ impl TestCase { | |
name: name.into(), | ||
classname: None, | ||
assertions: None, | ||
#[cfg(feature = "timestamps")] | ||
timestamp: None, | ||
time: None, | ||
status, | ||
|
@@ -360,6 +378,7 @@ impl TestCase { | |
} | ||
|
||
/// Sets the start timestamp for the test case. | ||
#[cfg(feature = "timestamps")] | ||
pub fn set_timestamp(&mut self, timestamp: impl Into<DateTime<FixedOffset>>) -> &mut Self { | ||
self.timestamp = Some(timestamp.into()); | ||
self | ||
|
@@ -548,6 +567,7 @@ pub struct TestRerun { | |
/// The time at which this rerun began execution. | ||
/// | ||
/// This is not part of the JUnit spec, but may be useful for some tools. | ||
#[cfg(feature = "timestamps")] | ||
pub timestamp: Option<DateTime<FixedOffset>>, | ||
|
||
/// The time it took to execute this rerun. | ||
|
@@ -581,6 +601,7 @@ impl TestRerun { | |
pub fn new(kind: NonSuccessKind) -> Self { | ||
TestRerun { | ||
kind, | ||
#[cfg(feature = "timestamps")] | ||
timestamp: None, | ||
time: None, | ||
message: None, | ||
|
@@ -593,6 +614,7 @@ impl TestRerun { | |
} | ||
|
||
/// Sets the start timestamp for this rerun. | ||
#[cfg(feature = "timestamps")] | ||
pub fn set_timestamp(&mut self, timestamp: impl Into<DateTime<FixedOffset>>) -> &mut Self { | ||
self.timestamp = Some(timestamp.into()); | ||
self | ||
|
@@ -718,6 +740,7 @@ impl XmlString { | |
/// Creates a new `XmlString`, removing any ANSI escapes and non-printable characters from it. | ||
pub fn new(data: impl AsRef<str>) -> Self { | ||
let data = data.as_ref(); | ||
#[cfg(feature = "strip-ansi")] | ||
let data = strip_ansi_escapes::strip_str(data); | ||
Comment on lines
+743
to
744
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't right -- enabling a feature shouldn't cause this kind of behavior change. Instead I'd recommend adding an alternative constructor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To clarify, you mean something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For backwards compatibility, I think Oh it looks like in the loop below, it's quick-junit that's doing the filtering of illegal bytes. |
||
let data = data | ||
.replace( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<testsuites name="my-test-run" tests="7" failures="2" errors="1" time="42.235"> | ||
<testsuite name="testsuite0" tests="7" disabled="1" errors="1" failures="2"> | ||
<properties> | ||
<property name="env" value="FOOBAR"/> | ||
</properties> | ||
<testcase name="testcase0"> | ||
<system-out>testcase0-output</system-out> | ||
</testcase> | ||
<testcase name="testcase1" time="4.242"> | ||
<failure message="testcase1-message">this is the failure description</failure> | ||
<system-err>some sort of failure output</system-err> | ||
</testcase> | ||
<testcase name="testcase2" time="0.000"> | ||
<error type="error type">testcase2 error description</error> | ||
</testcase> | ||
<testcase name="testcase3" assertions="20"> | ||
<skipped message="skipped message" type="skipped type"/> | ||
<system-out>testcase3 output</system-out> | ||
<system-err>testcase3 error</system-err> | ||
</testcase> | ||
<testcase name="testcase4" time="661.661"> | ||
<flakyFailure type="flaky failure type">this is a flaky failure description</flakyFailure> | ||
<flakyError type="flaky error type">flaky error description | ||
<stackTrace>flaky stack trace</stackTrace> | ||
<system-out>flaky system output</system-out> | ||
<system-err>flaky system error with [34mANSI escape codes[39m</system-err> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Without the ansi-escape feature flag, ANSI escape codes are just added to the XML. It looks like there is actually no additional escaping necessary to be valid XML (but if it were, quick-xml would take care of it). Of course we shouldn't have unescaped ANSI codes in here, but in many cases you may know that the target application is never producing them in the first place. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting -- I think a newer version of quick-xml might be doing some filtering here. |
||
</flakyError> | ||
</testcase> | ||
<testcase name="testcase5" time="0.156"> | ||
<failure>main test failure description</failure> | ||
<rerunFailure type="retry failure type"> | ||
</rerunFailure> | ||
<rerunError type="retry error type"> | ||
<stackTrace>retry error stack trace</stackTrace> | ||
<system-out>retry error system output</system-out> | ||
</rerunError> | ||
</testcase> | ||
<testcase name="testcase6"> | ||
<properties> | ||
<property name="step" value="foobar"/> | ||
</properties> | ||
</testcase> | ||
</testsuite> | ||
</testsuites> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd make
timestamps
default and the other two non-default.