testing_language_server/
spec.rs

1use clap::Parser;
2use lsp_types::Diagnostic;
3use lsp_types::Range;
4use lsp_types::ShowMessageParams;
5use serde::Deserialize;
6use serde::Serialize;
7use std::collections::HashMap;
8
9#[derive(Parser, Debug)]
10pub enum AdapterCommands {
11    Discover(DiscoverArgs),
12    RunFileTest(RunFileTestArgs),
13    DetectWorkspace(DetectWorkspaceArgs),
14}
15
16/// Arguments for `<adapter command> discover` command
17#[derive(clap::Args, Debug)]
18#[command(version, about, long_about = None)]
19pub struct DiscoverArgs {
20    #[arg(short, long)]
21    pub file_paths: Vec<String>,
22    #[arg(last = true)]
23    pub extra: Vec<String>,
24}
25
26/// Arguments for `<adapter command> run-file-test` command
27#[derive(clap::Args, Debug)]
28#[command(version, about, long_about = None)]
29pub struct RunFileTestArgs {
30    #[arg(short, long)]
31    pub file_paths: Vec<String>,
32
33    #[arg(short, long)]
34    pub workspace: String,
35
36    #[arg(last = true)]
37    pub extra: Vec<String>,
38}
39
40/// Arguments for `<adapter command> detect-workspace` command
41#[derive(clap::Args, Debug)]
42#[command(version, about, long_about = None)]
43pub struct DetectWorkspaceArgs {
44    #[arg(short, long)]
45    pub file_paths: Vec<String>,
46    #[arg(last = true)]
47    pub extra: Vec<String>,
48}
49
50pub type AdapterId = String;
51pub type FilePath = String;
52pub type WorkspaceFilePath = String;
53
54#[derive(Debug, Serialize, Clone)]
55pub struct WorkspaceAnalysis {
56    pub adapter_config: AdapterConfiguration,
57    pub workspaces: DetectWorkspaceResult,
58}
59
60impl WorkspaceAnalysis {
61    pub fn new(adapter_config: AdapterConfiguration, workspaces: DetectWorkspaceResult) -> Self {
62        Self {
63            adapter_config,
64            workspaces,
65        }
66    }
67}
68
69#[derive(Debug, Deserialize, Clone, Serialize, Default)]
70pub struct AdapterConfiguration {
71    pub path: String,
72    #[serde(default)]
73    pub extra_arg: Vec<String>,
74    #[serde(default)]
75    pub env: HashMap<String, String>,
76    pub include: Vec<String>,
77    pub exclude: Vec<String>,
78    pub workspace_dir: Option<String>,
79}
80
81/// Result of `<adapter command> detect-workspace`
82#[derive(Debug, Serialize, Clone, Deserialize)]
83pub struct DetectWorkspaceResult {
84    pub data: HashMap<WorkspaceFilePath, Vec<FilePath>>,
85}
86
87#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
88pub struct FileDiagnostics {
89    pub path: String,
90    pub diagnostics: Vec<Diagnostic>,
91}
92
93/// Result of `<adapter command> run-file-test`
94#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
95pub struct RunFileTestResult {
96    pub data: Vec<FileDiagnostics>,
97    #[serde(default)]
98    pub messages: Vec<ShowMessageParams>,
99}
100
101#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
102pub struct TestItem {
103    pub id: String,
104    pub name: String,
105    /// Although FoundFileTests also has a `path` field, we keep the `path` field in TestItem
106    /// because sometimes we need to determine where a TestItem is located on its own
107    /// Example: In Rust tests, determining which file contains a test from IDs like relative::path::tests::id
108    /// TODO: Remove FoundFileTests.path once we confirm it's no longer needed
109    pub path: String,
110    pub start_position: Range,
111    pub end_position: Range,
112}
113
114#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
115pub struct FoundFileTests {
116    pub path: String,
117    pub tests: Vec<TestItem>,
118}
119
120/// Result of `<adapter command> discover`
121#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
122pub struct DiscoverResult {
123    pub data: Vec<FoundFileTests>,
124}