diff --git a/codex-rs/core/src/tools/mod.rs b/codex-rs/core/src/tools/mod.rs index 37b71fd30e..9fe38d6a59 100644 --- a/codex-rs/core/src/tools/mod.rs +++ b/codex-rs/core/src/tools/mod.rs @@ -320,57 +320,6 @@ pub fn format_exec_output_structured(exec_output: &ExecToolCallOutput) -> String sections.join("\n") } -#[cfg(test)] -mod tests { - use super::*; - use crate::exec::StreamOutput; - use pretty_assertions::assert_eq; - use std::time::Duration; - - fn sample_output() -> ExecToolCallOutput { - ExecToolCallOutput { - exit_code: 0, - stdout: StreamOutput::new("stdout".to_string()), - stderr: StreamOutput::new("stderr".to_string()), - aggregated_output: StreamOutput::new("stdout\nstderr".to_string()), - duration: Duration::from_secs_f64(1.2345), - timed_out: false, - } - } - - #[test] - fn structured_format_basic() { - let formatted = format_exec_output_structured(&sample_output()); - let expected = "Exit code: 0\nWall time: 1.235 seconds\nOutput:\nstdout\nstderr"; - assert_eq!(formatted, expected); - } - - #[test] - fn structured_format_includes_truncation_metadata() { - let mut output = sample_output(); - output.aggregated_output.truncated_after_lines = Some(200); - let formatted = format_exec_output_structured(&output); - assert!(formatted.contains("Total output lines: 200")); - } - - #[test] - fn significant_digit_formatting_matches_expectations() { - assert_eq!(format_significant_digits(0.0, 4), "0"); - assert_eq!(format_significant_digits(1.23456, 4), "1.235"); - assert_eq!(format_significant_digits(12345.0, 4), "1.235e4"); - assert_eq!(format_significant_digits(0.000123456, 4), "0.0001235"); - } - - #[test] - fn structured_error_includes_metadata() { - let error = format_structured_error("unexpected failure"); - assert_eq!( - error, - "Exit code: N/A\nWall time: N/A seconds\nError: unexpected failure\nOutput:\n" - ); - } -} - pub fn format_exec_output_str(exec_output: &ExecToolCallOutput) -> String { let ExecToolCallOutput { aggregated_output, .. @@ -448,3 +397,89 @@ pub fn format_exec_output_str(exec_output: &ExecToolCallOutput) -> String { result } + +#[cfg(test)] +mod tests { + use super::*; + use crate::exec::StreamOutput; + use pretty_assertions::assert_eq; + use std::time::Duration; + const TRUNCATED_STRUCTURED_EXPECTED: &str = + include_str!("tests/truncated_structured_expected.txt"); + + fn sample_output() -> ExecToolCallOutput { + ExecToolCallOutput { + exit_code: 0, + stdout: StreamOutput::new("stdout".to_string()), + stderr: StreamOutput::new("stderr".to_string()), + aggregated_output: StreamOutput::new("stdout\nstderr".to_string()), + duration: Duration::from_secs_f64(1.2345), + timed_out: false, + } + } + + #[test] + fn structured_format_basic() { + let formatted = format_exec_output_structured(&sample_output()); + let expected = "Exit code: 0\nWall time: 1.235 seconds\nOutput:\nstdout\nstderr"; + assert_eq!(formatted, expected); + } + + #[test] + fn structured_format_includes_truncation_metadata() { + let mut output = sample_output(); + output.aggregated_output.truncated_after_lines = Some(200); + let formatted = format_exec_output_structured(&output); + assert!(formatted.contains("Total output lines: 200")); + } + + #[test] + fn significant_digit_formatting_matches_expectations() { + assert_eq!(format_significant_digits(0.0, 4), "0"); + assert_eq!(format_significant_digits(1.23456, 4), "1.235"); + assert_eq!(format_significant_digits(12345.0, 4), "1.235e4"); + assert_eq!(format_significant_digits(0.000123456, 4), "0.0001235"); + } + + #[test] + fn structured_error_includes_metadata() { + let error = format_structured_error("unexpected failure"); + assert_eq!( + error, + "Exit code: N/A\nWall time: N/A seconds\nError: unexpected failure\nOutput:\n" + ); + } + + #[test] + fn format_exec_output_uses_legacy_json_formatter() { + let output = sample_output(); + let formatted = format_exec_output(&output, ExecResponseFormat::LegacyJson); + assert_eq!( + formatted, + "{\"output\":\"stdout\\nstderr\",\"metadata\":{\"exit_code\":0,\"duration_seconds\":1.2}}" + ); + } + + #[test] + fn format_exec_output_uses_structured_formatter() { + let output = sample_output(); + let formatted = format_exec_output(&output, ExecResponseFormat::StructuredText); + assert_eq!( + formatted, + "Exit code: 0\nWall time: 1.235 seconds\nOutput:\nstdout\nstderr" + ); + } + + #[test] + fn format_exec_output_truncates_long_output() { + let mut output = sample_output(); + let mut aggregated = String::new(); + for i in 0..260 { + aggregated.push_str(&format!("L{i:03}\n")); + } + output.aggregated_output = StreamOutput::new(aggregated); + + let formatted = format_exec_output(&output, ExecResponseFormat::StructuredText); + assert_eq!(formatted, TRUNCATED_STRUCTURED_EXPECTED); + } +} diff --git a/codex-rs/core/src/tools/tests/truncated_structured_expected.txt b/codex-rs/core/src/tools/tests/truncated_structured_expected.txt new file mode 100644 index 0000000000..bd48439c82 --- /dev/null +++ b/codex-rs/core/src/tools/tests/truncated_structured_expected.txt @@ -0,0 +1,262 @@ +Exit code: 0 +Wall time: 1.235 seconds +Output: +L000 +L001 +L002 +L003 +L004 +L005 +L006 +L007 +L008 +L009 +L010 +L011 +L012 +L013 +L014 +L015 +L016 +L017 +L018 +L019 +L020 +L021 +L022 +L023 +L024 +L025 +L026 +L027 +L028 +L029 +L030 +L031 +L032 +L033 +L034 +L035 +L036 +L037 +L038 +L039 +L040 +L041 +L042 +L043 +L044 +L045 +L046 +L047 +L048 +L049 +L050 +L051 +L052 +L053 +L054 +L055 +L056 +L057 +L058 +L059 +L060 +L061 +L062 +L063 +L064 +L065 +L066 +L067 +L068 +L069 +L070 +L071 +L072 +L073 +L074 +L075 +L076 +L077 +L078 +L079 +L080 +L081 +L082 +L083 +L084 +L085 +L086 +L087 +L088 +L089 +L090 +L091 +L092 +L093 +L094 +L095 +L096 +L097 +L098 +L099 +L100 +L101 +L102 +L103 +L104 +L105 +L106 +L107 +L108 +L109 +L110 +L111 +L112 +L113 +L114 +L115 +L116 +L117 +L118 +L119 +L120 +L121 +L122 +L123 +L124 +L125 +L126 +L127 + +[... omitted 4 of 260 lines ...] + +L132 +L133 +L134 +L135 +L136 +L137 +L138 +L139 +L140 +L141 +L142 +L143 +L144 +L145 +L146 +L147 +L148 +L149 +L150 +L151 +L152 +L153 +L154 +L155 +L156 +L157 +L158 +L159 +L160 +L161 +L162 +L163 +L164 +L165 +L166 +L167 +L168 +L169 +L170 +L171 +L172 +L173 +L174 +L175 +L176 +L177 +L178 +L179 +L180 +L181 +L182 +L183 +L184 +L185 +L186 +L187 +L188 +L189 +L190 +L191 +L192 +L193 +L194 +L195 +L196 +L197 +L198 +L199 +L200 +L201 +L202 +L203 +L204 +L205 +L206 +L207 +L208 +L209 +L210 +L211 +L212 +L213 +L214 +L215 +L216 +L217 +L218 +L219 +L220 +L221 +L222 +L223 +L224 +L225 +L226 +L227 +L228 +L229 +L230 +L231 +L232 +L233 +L234 +L235 +L236 +L237 +L238 +L239 +L240 +L241 +L242 +L243 +L244 +L245 +L246 +L247 +L248 +L249 +L250 +L251 +L252 +L253 +L254 +L255 +L256 +L257 +L258 +L259