1pub mod backend;
2pub mod domain;
3pub mod repositories;
4pub mod services;
5
6pub use backend::*;
7
8#[cfg(test)]
9mod tests {
10 use crate::domain::{BkmrSnippet, LanguageRegistry, SnippetFilter};
11 use crate::services::LanguageTranslator;
12 use tower_lsp::lsp_types::Url;
13
14 #[test]
15 fn given_universal_and_regular_snippets_when_checking_tags_then_detects_universal_correctly() {
16 let universal_snippet = BkmrSnippet {
18 id: 1,
19 title: "Test Universal Snippet".to_string(),
20 url: "// This is a test".to_string(),
21 description: "Test description".to_string(),
22 tags: vec!["universal".to_string(), "test".to_string()],
23 access_count: 0,
24 };
25
26 let regular_snippet = BkmrSnippet {
27 id: 2,
28 title: "Test Regular Snippet".to_string(),
29 url: "// This is a test".to_string(),
30 description: "Test description".to_string(),
31 tags: vec!["rust".to_string(), "test".to_string()],
32 access_count: 0,
33 };
34
35 assert!(universal_snippet.tags.contains(&"universal".to_string()));
37 assert!(!regular_snippet.tags.contains(&"universal".to_string()));
38 }
39
40 #[test]
41 fn given_rust_line_comments_when_translating_to_python_then_converts_to_hash_comments() {
42 let uri = Url::parse("file:///test/example.py").expect("valid test URI");
44 let rust_content = r#"// This is a line comment
45 // Indented comment
46let x = 5; // End of line comment"#;
47
48 let python_result =
50 LanguageTranslator::translate_rust_patterns(rust_content, "python", &uri)
51 .expect("translation should succeed");
52
53 assert!(python_result.contains("# This is a line comment"));
55 assert!(python_result.contains(" # Indented comment"));
56 assert!(python_result.contains("let x = 5; # End of line comment"));
57
58 let html_result = LanguageTranslator::translate_rust_patterns(rust_content, "html", &uri)
60 .expect("translation should succeed");
61 assert!(html_result.contains("<!-- This is a line comment -->"));
62 assert!(html_result.contains(" <!-- Indented comment -->")); assert!(html_result.contains("let x = 5; <!-- End of line comment -->"));
64 }
65
66 #[test]
67 fn test_rust_block_comment_translation() {
68 let uri = Url::parse("file:///test/example.py").expect("valid test URI");
69
70 let rust_content = r#"/* This is a block comment */
71/*
72Multi-line
73block comment
74*/"#;
75
76 let python_result =
77 LanguageTranslator::translate_rust_patterns(rust_content, "python", &uri)
78 .expect("translation should succeed");
79 assert!(python_result.contains("\"\"\" This is a block comment \"\"\""));
80 assert!(python_result.contains("\"\"\"\nMulti-line\nblock comment\n\"\"\""));
81
82 let html_result = LanguageTranslator::translate_rust_patterns(rust_content, "html", &uri)
83 .expect("translation should succeed");
84 assert!(html_result.contains("<!-- This is a block comment -->"));
85 assert!(html_result.contains("<!--\nMulti-line\nblock comment\n-->"));
86 }
87
88 #[test]
89 fn test_rust_indentation_translation() {
90 let uri = Url::parse("file:///test/example.go").expect("valid Go test URI");
91
92 let rust_content = r#"fn example() {
93 let x = 5;
94 let y = 10;
95 let z = 15;
96}"#;
97
98 let go_result = LanguageTranslator::translate_rust_patterns(rust_content, "go", &uri)
100 .expect("translation should succeed");
101 assert!(go_result.contains("fn example() {"));
102 assert!(go_result.contains("\tlet x = 5;"));
103 assert!(go_result.contains("\t\tlet y = 10;"));
104 assert!(go_result.contains("\t\t\tlet z = 15;"));
105
106 let js_result =
108 LanguageTranslator::translate_rust_patterns(rust_content, "javascript", &uri)
109 .expect("translation should succeed");
110 assert!(js_result.contains(" let x = 5;"));
111 assert!(js_result.contains(" let y = 10;"));
112 assert!(js_result.contains(" let z = 15;"));
113 }
114
115 #[test]
116 fn test_filename_replacement() {
117 let uri = Url::parse("file:///path/to/example.rs").expect("valid Rust test URI");
118
119 let content = "// File: {{ filename }}";
120 let result = LanguageTranslator::translate_rust_patterns(content, "rust", &uri)
121 .expect("translation should succeed");
122 assert!(result.contains("// File: example.rs"));
123 }
124
125 #[test]
126 fn test_mixed_pattern_translation() {
127 let uri = Url::parse("file:///test/example.py").expect("valid test URI");
128
129 let rust_content = r#"// Function: {{ function_name }}
130// File: {{ filename }}
131fn {{ function_name }}() {
132 // TODO: implement
133 /* Block comment here */
134 let value = "hello";
135}"#;
136
137 let python_result =
138 LanguageTranslator::translate_rust_patterns(rust_content, "python", &uri)
139 .expect("translation should succeed");
140
141 assert!(python_result.contains("# Function: {{ function_name }}"));
143 assert!(python_result.contains("# File: example.py"));
144 assert!(python_result.contains(" # TODO: implement"));
145 assert!(python_result.contains("\"\"\" Block comment here \"\"\""));
146
147 assert!(python_result.contains("{{ function_name }}"));
149
150 assert!(python_result.contains(" let value = \"hello\";"));
152 }
153
154 #[test]
155 fn test_language_info_retrieval() {
156 let rust_info = LanguageRegistry::get_language_info("rust");
157 assert_eq!(rust_info.line_comment, Some("//".to_string()));
158 assert_eq!(
159 rust_info.block_comment,
160 Some(("/*".to_string(), "*/".to_string()))
161 );
162 assert_eq!(rust_info.indent_char, " ");
163
164 let python_info = LanguageRegistry::get_language_info("python");
165 assert_eq!(python_info.line_comment, Some("#".to_string()));
166 assert_eq!(
167 python_info.block_comment,
168 Some(("\"\"\"".to_string(), "\"\"\"".to_string()))
169 );
170 assert_eq!(python_info.indent_char, " ");
171
172 let go_info = LanguageRegistry::get_language_info("go");
173 assert_eq!(go_info.line_comment, Some("//".to_string()));
174 assert_eq!(go_info.indent_char, "\t");
175
176 let html_info = LanguageRegistry::get_language_info("html");
177 assert_eq!(html_info.line_comment, None);
178 assert_eq!(
179 html_info.block_comment,
180 Some(("<!--".to_string(), "-->".to_string()))
181 );
182 assert_eq!(html_info.indent_char, " ");
183 }
184
185 #[test]
186 fn test_edge_cases() {
187 let uri = Url::parse("file:///test/example.py").expect("valid test URI");
188
189 let result = LanguageTranslator::translate_rust_patterns("", "python", &uri)
191 .expect("translation should succeed");
192 assert_eq!(result, "");
193
194 let no_patterns = "Just plain text here";
196 let result = LanguageTranslator::translate_rust_patterns(no_patterns, "python", &uri)
197 .expect("translation should succeed");
198 assert_eq!(result, no_patterns);
199
200 let string_comments = r#"let url = "https://example.com"; // Real comment"#;
202 let result = LanguageTranslator::translate_rust_patterns(string_comments, "python", &uri)
203 .expect("translation should succeed");
204 assert!(result.contains("\"https://example.com\""));
205 assert!(result.contains("# Real comment"));
206
207 let multi_line = "//Comment1\n//Comment2\n //Comment3";
209 let result = LanguageTranslator::translate_rust_patterns(multi_line, "python", &uri)
210 .expect("translation should succeed");
211 assert!(result.contains("# Comment1"));
212 assert!(result.contains("# Comment2"));
213 assert!(result.contains(" # Comment3"));
214 }
215
216 #[test]
217 fn test_fts_query_builder() {
218 let filter = SnippetFilter::new(Some("markdown".to_string()), None, 50);
220 let query = filter.build_fts_query();
221 assert_eq!(
222 query,
223 Some(
224 r#"(tags:markdown AND tags:"_snip_") OR (tags:universal AND tags:"_snip_")"#
225 .to_string()
226 )
227 );
228
229 let filter = SnippetFilter::new(Some("rust".to_string()), None, 50);
231 let query = filter.build_fts_query();
232 assert_eq!(
233 query,
234 Some(
235 r#"(tags:rust AND tags:"_snip_") OR (tags:universal AND tags:"_snip_")"#
236 .to_string()
237 )
238 );
239
240 let filter = SnippetFilter::new(Some("".to_string()), None, 50);
242 let query = filter.build_fts_query();
243 assert_eq!(query, Some(r#"tags:"_snip_""#.to_string()));
244
245 let filter = SnippetFilter::new(Some(" ".to_string()), None, 50);
247 let query = filter.build_fts_query();
248 assert_eq!(query, Some(r#"tags:"_snip_""#.to_string()));
249
250 let filter = SnippetFilter::new(None, None, 50);
252 let query = filter.build_fts_query();
253 assert_eq!(query, Some(r#"tags:"_snip_""#.to_string()));
254
255 let filter = SnippetFilter::new(Some("typescript".to_string()), None, 50);
257 let query = filter.build_fts_query();
258 assert_eq!(
259 query,
260 Some(
261 r#"(tags:typescript AND tags:"_snip_") OR (tags:universal AND tags:"_snip_")"#
262 .to_string()
263 )
264 );
265 }
266
267 #[test]
268 fn test_multiline_universal_snippet_processing() {
269 let uri = Url::parse("file:///test/example.py").expect("valid test URI");
271 let multiline_content = "{% raw %}\n// Fold description {{{ //\n\nContent\n// }}} Fold description //\n$0\n{% endraw %}";
272
273 println!("Input content: {:?}", multiline_content);
274 println!(
275 "Input lines: {:?}",
276 multiline_content.split('\n').collect::<Vec<_>>()
277 );
278
279 let result = LanguageTranslator::translate_rust_patterns(multiline_content, "python", &uri)
280 .expect("translation should succeed");
281
282 println!("Output content: {:?}", result);
283 println!("Output lines: {:?}", result.split('\n').collect::<Vec<_>>());
284
285 let input_line_count = multiline_content.matches('\n').count();
287 let output_line_count = result.matches('\n').count();
288
289 println!(
290 "Input newlines: {}, Output newlines: {}",
291 input_line_count, output_line_count
292 );
293
294 assert_eq!(
296 input_line_count, output_line_count,
297 "Number of newlines should be preserved"
298 );
299
300 assert!(result.contains("# Fold description {{{ //"));
302 assert!(result.contains("# }}} Fold description //"));
303
304 assert!(result.contains("\n\nContent\n"));
306 }
307}