changepacks_cli/options/
filter_options.rs1use changepacks_core::Project;
2use clap::ValueEnum;
3
4#[derive(Debug, Clone, ValueEnum)]
8pub enum FilterOptions {
9 Workspace,
11 Package,
13}
14
15impl FilterOptions {
16 #[must_use]
17 pub fn matches(&self, project: &Project) -> bool {
18 match self {
19 Self::Workspace => matches!(project, Project::Workspace(_)),
20 Self::Package => matches!(project, Project::Package(_)),
21 }
22 }
23}
24
25#[cfg(test)]
26mod tests {
27 use super::*;
28 use async_trait::async_trait;
29 use changepacks_core::{Language, Package, UpdateType, Workspace};
30 use clap::ValueEnum;
31 use std::collections::HashSet;
32 use std::path::{Path, PathBuf};
33
34 #[derive(Debug)]
35 struct MockPackage {
36 name: Option<String>,
37 path: PathBuf,
38 relative_path: PathBuf,
39 version: Option<String>,
40 language: Language,
41 dependencies: HashSet<String>,
42 changed: bool,
43 }
44
45 #[async_trait]
46 impl Package for MockPackage {
47 fn name(&self) -> Option<&str> {
48 self.name.as_deref()
49 }
50
51 fn version(&self) -> Option<&str> {
52 self.version.as_deref()
53 }
54
55 fn path(&self) -> &Path {
56 &self.path
57 }
58
59 fn relative_path(&self) -> &Path {
60 &self.relative_path
61 }
62
63 async fn update_version(&mut self, _update_type: UpdateType) -> anyhow::Result<()> {
64 Ok(())
65 }
66
67 fn is_changed(&self) -> bool {
68 self.changed
69 }
70
71 fn language(&self) -> Language {
72 self.language
73 }
74
75 fn dependencies(&self) -> &HashSet<String> {
76 &self.dependencies
77 }
78
79 fn add_dependency(&mut self, dependency: &str) {
80 self.dependencies.insert(dependency.to_string());
81 }
82
83 fn set_changed(&mut self, changed: bool) {
84 self.changed = changed;
85 }
86
87 fn default_publish_command(&self) -> String {
88 "echo publish".to_string()
89 }
90 }
91
92 #[derive(Debug)]
93 struct MockWorkspace {
94 name: Option<String>,
95 path: PathBuf,
96 relative_path: PathBuf,
97 version: Option<String>,
98 language: Language,
99 dependencies: HashSet<String>,
100 changed: bool,
101 }
102
103 #[async_trait]
104 impl Workspace for MockWorkspace {
105 fn name(&self) -> Option<&str> {
106 self.name.as_deref()
107 }
108
109 fn version(&self) -> Option<&str> {
110 self.version.as_deref()
111 }
112
113 fn path(&self) -> &Path {
114 &self.path
115 }
116
117 fn relative_path(&self) -> &Path {
118 &self.relative_path
119 }
120
121 async fn update_version(&mut self, _update_type: UpdateType) -> anyhow::Result<()> {
122 Ok(())
123 }
124
125 fn is_changed(&self) -> bool {
126 self.changed
127 }
128
129 fn language(&self) -> Language {
130 self.language
131 }
132
133 fn dependencies(&self) -> &HashSet<String> {
134 &self.dependencies
135 }
136
137 fn add_dependency(&mut self, dependency: &str) {
138 self.dependencies.insert(dependency.to_string());
139 }
140
141 fn set_changed(&mut self, changed: bool) {
142 self.changed = changed;
143 }
144
145 fn default_publish_command(&self) -> String {
146 "echo publish".to_string()
147 }
148
149 async fn update_workspace_dependencies(
150 &self,
151 _packages: &[&dyn Package],
152 ) -> anyhow::Result<()> {
153 Ok(())
154 }
155 }
156
157 fn workspace_project() -> Project {
158 Project::Workspace(Box::new(MockWorkspace {
159 name: Some("workspace".to_string()),
160 path: PathBuf::from("/repo/package.json"),
161 relative_path: PathBuf::from("package.json"),
162 version: Some("1.0.0".to_string()),
163 language: Language::Node,
164 dependencies: HashSet::new(),
165 changed: false,
166 }))
167 }
168
169 fn package_project() -> Project {
170 Project::Package(Box::new(MockPackage {
171 name: Some("package".to_string()),
172 path: PathBuf::from("/repo/crates/pkg/Cargo.toml"),
173 relative_path: PathBuf::from("crates/pkg/Cargo.toml"),
174 version: Some("1.0.0".to_string()),
175 language: Language::Rust,
176 dependencies: HashSet::new(),
177 changed: false,
178 }))
179 }
180
181 #[test]
182 fn test_filter_options_matches_workspace_with_workspace_project() {
183 let project = workspace_project();
184 assert!(FilterOptions::Workspace.matches(&project));
185 }
186
187 #[test]
188 fn test_filter_options_matches_workspace_with_package_project() {
189 let project = package_project();
190 assert!(!FilterOptions::Workspace.matches(&project));
191 }
192
193 #[test]
194 fn test_filter_options_matches_package_with_package_project() {
195 let project = package_project();
196 assert!(FilterOptions::Package.matches(&project));
197 }
198
199 #[test]
200 fn test_filter_options_matches_package_with_workspace_project() {
201 let project = workspace_project();
202 assert!(!FilterOptions::Package.matches(&project));
203 }
204
205 #[test]
206 fn test_filter_options_value_enum_workspace() {
207 let filter = FilterOptions::from_str("workspace", true).unwrap();
208 assert!(matches!(filter, FilterOptions::Workspace));
209 }
210
211 #[test]
212 fn test_filter_options_value_enum_package() {
213 let filter = FilterOptions::from_str("package", true).unwrap();
214 assert!(matches!(filter, FilterOptions::Package));
215 }
216}