From 35a5fd767de55e8a6f193cb2db33f58676354d63 Mon Sep 17 00:00:00 2001 From: Douglas Creager Date: Wed, 8 Oct 2025 13:52:58 -0400 Subject: [PATCH] [ty_test] Extract HoverOutput type from CheckOutput enum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create a dedicated HoverOutput struct to hold hover result data, replacing the inline fields in CheckOutput::Hover variant. This allows implementing Unmatched and UnmatchedWithColumn traits directly on HoverOutput, simplifying the CheckOutput implementations to simple delegation. Benefits: - Better separation of concerns - Cleaner trait implementations - More consistent with Diagnostic handling - Easier to extend HoverOutput in the future 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- crates/ty_test/src/check_output.rs | 18 ++++++++++------ crates/ty_test/src/hover.rs | 6 +++--- crates/ty_test/src/matcher.rs | 34 ++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/crates/ty_test/src/check_output.rs b/crates/ty_test/src/check_output.rs index 3bebfbd92c..df26bdcd63 100644 --- a/crates/ty_test/src/check_output.rs +++ b/crates/ty_test/src/check_output.rs @@ -8,6 +8,15 @@ use ruff_source_file::{LineIndex, OneIndexed}; use ruff_text_size::TextSize; use std::ops::Range; +/// A hover result for testing hover assertions. +#[derive(Debug, Clone)] +pub(crate) struct HoverOutput { + /// The position where hover was requested + pub(crate) offset: TextSize, + /// The inferred type at that position + pub(crate) inferred_type: String, +} + /// Represents either a diagnostic or a hover result for matching against assertions. #[derive(Debug, Clone)] pub(crate) enum CheckOutput { @@ -15,12 +24,7 @@ pub(crate) enum CheckOutput { Diagnostic(Diagnostic), /// A hover result for testing hover assertions - Hover { - /// The position where hover was requested - offset: TextSize, - /// The inferred type at that position - inferred_type: String, - }, + Hover(HoverOutput), } impl CheckOutput { @@ -32,7 +36,7 @@ impl CheckOutput { .map_or(OneIndexed::from_zero_indexed(0), |range| { line_index.line_index(range.start()) }), - CheckOutput::Hover { offset, .. } => line_index.line_index(*offset), + CheckOutput::Hover(hover) => line_index.line_index(hover.offset), } } } diff --git a/crates/ty_test/src/hover.rs b/crates/ty_test/src/hover.rs index 915f3ecc8b..1c4fb90321 100644 --- a/crates/ty_test/src/hover.rs +++ b/crates/ty_test/src/hover.rs @@ -3,7 +3,7 @@ //! This module provides functionality to extract hover assertions from comments, //! infer types at specified positions, and generate hover check outputs for matching. -use crate::check_output::CheckOutput; +use crate::check_output::{CheckOutput, HoverOutput}; use ruff_db::files::File; use ruff_db::parsed::parsed_module; use ruff_db::source::{line_index, source_text}; @@ -107,10 +107,10 @@ pub(crate) fn generate_hover_outputs( continue; }; - hover_outputs.push(CheckOutput::Hover { + hover_outputs.push(CheckOutput::Hover(HoverOutput { offset: hover_offset, inferred_type, - }); + })); } } diff --git a/crates/ty_test/src/matcher.rs b/crates/ty_test/src/matcher.rs index 4969be9f35..cc6cf8ac4e 100644 --- a/crates/ty_test/src/matcher.rs +++ b/crates/ty_test/src/matcher.rs @@ -12,7 +12,7 @@ use ruff_db::source::{SourceText, line_index, source_text}; use ruff_source_file::{LineIndex, OneIndexed}; use crate::assertion::{InlineFileAssertions, ParsedAssertion, UnparsedAssertion}; -use crate::check_output::{CheckOutput, LineCheckOutputs, SortedCheckOutputs}; +use crate::check_output::{CheckOutput, HoverOutput, LineCheckOutputs, SortedCheckOutputs}; use crate::db::Db; #[derive(Debug, Default)] @@ -174,13 +174,28 @@ impl Unmatched for CheckOutput { fn unmatched(&self) -> String { match self { CheckOutput::Diagnostic(diag) => diag.unmatched(), - CheckOutput::Hover { inferred_type, .. } => { - format!("{} hover result: {inferred_type}", "unexpected:".red()) - } + CheckOutput::Hover(hover) => hover.unmatched(), } } } +impl Unmatched for &HoverOutput { + fn unmatched(&self) -> String { + format!("{} hover result: {}", "unexpected:".red(), self.inferred_type) + } +} + +impl UnmatchedWithColumn for &HoverOutput { + fn unmatched_with_column(&self, column: OneIndexed) -> String { + format!( + "{} {} hover result: {}", + "unexpected:".red(), + column, + self.inferred_type + ) + } +} + impl Unmatched for &Diagnostic { fn unmatched(&self) -> String { maybe_add_undefined_reveal_clarification( @@ -267,8 +282,8 @@ impl Matcher { CheckOutput::Diagnostic(diag) => { failures.push(diag.unmatched_with_column(self.column(diag))); } - CheckOutput::Hover { inferred_type, .. } => { - failures.push(format!("{} hover result: {inferred_type}", "unexpected:".red())); + CheckOutput::Hover(hover) => { + failures.push(hover.unmatched()); } } } @@ -401,15 +416,12 @@ impl Matcher { // Find a hover output that matches the expected type let position = unmatched.iter().position(|output| { - let CheckOutput::Hover { - inferred_type, .. - } = output - else { + let CheckOutput::Hover(hover_output) = output else { return false; }; // Compare the inferred type with the expected type - let inferred_type = discard_todo_metadata(inferred_type); + let inferred_type = discard_todo_metadata(&hover_output.inferred_type); inferred_type == expected_type });