Skip to content

Commit f52f55c

Browse files
unhappychoiceclaude
andcommitted
test: reorganize language extraction tests
- Create tests/integration/languages/ structure - Move language-specific tests to separate files - Add modular test organization for better maintainability - Support Rust, TypeScript, Ruby, Go, Swift, Kotlin, Python tests 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 8f26db3 commit f52f55c

File tree

9 files changed

+1479
-0
lines changed

9 files changed

+1479
-0
lines changed

tests/integration/languages/go.rs

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
use gittype::extractor::{ChunkType, CodeExtractor, ExtractionOptions};
2+
use std::fs;
3+
use tempfile::TempDir;
4+
5+
#[test]
6+
fn test_go_function_extraction() {
7+
let temp_dir = TempDir::new().unwrap();
8+
let file_path = temp_dir.path().join("test.go");
9+
10+
let go_code = r#"package main
11+
12+
import "fmt"
13+
14+
func main() {
15+
fmt.Println("Hello, world!")
16+
}
17+
18+
func add(a, b int) int {
19+
return a + b
20+
}
21+
22+
func multiply(x int, y int) int {
23+
return x * y
24+
}
25+
"#;
26+
fs::write(&file_path, go_code).unwrap();
27+
28+
let mut extractor = CodeExtractor::new().unwrap();
29+
let chunks = extractor
30+
.extract_chunks(temp_dir.path(), ExtractionOptions::default())
31+
.unwrap();
32+
33+
assert_eq!(chunks.len(), 3);
34+
35+
let function_names: Vec<&String> = chunks.iter().map(|c| &c.name).collect();
36+
assert!(function_names.contains(&&"main".to_string()));
37+
assert!(function_names.contains(&&"add".to_string()));
38+
assert!(function_names.contains(&&"multiply".to_string()));
39+
40+
for chunk in &chunks {
41+
assert!(matches!(chunk.chunk_type, ChunkType::Function));
42+
assert_eq!(chunk.language, gittype::extractor::Language::Go);
43+
}
44+
}
45+
46+
#[test]
47+
fn test_go_struct_extraction() {
48+
let temp_dir = TempDir::new().unwrap();
49+
let file_path = temp_dir.path().join("test.go");
50+
51+
let go_code = r#"package main
52+
53+
type Person struct {
54+
Name string
55+
Age int
56+
}
57+
58+
type Address struct {
59+
Street string
60+
City string
61+
Zip string
62+
}
63+
64+
func (p Person) GetName() string {
65+
return p.Name
66+
}
67+
68+
func (a *Address) GetFullAddress() string {
69+
return a.Street + ", " + a.City + " " + a.Zip
70+
}
71+
"#;
72+
fs::write(&file_path, go_code).unwrap();
73+
74+
let mut extractor = CodeExtractor::new().unwrap();
75+
let chunks = extractor
76+
.extract_chunks(temp_dir.path(), ExtractionOptions::default())
77+
.unwrap();
78+
79+
assert_eq!(chunks.len(), 4); // 2 structs + 2 methods
80+
81+
// Find struct chunks
82+
let struct_chunks: Vec<_> = chunks
83+
.iter()
84+
.filter(|c| matches!(c.chunk_type, ChunkType::Struct))
85+
.collect();
86+
assert_eq!(struct_chunks.len(), 2);
87+
88+
let struct_names: Vec<&String> = struct_chunks.iter().map(|c| &c.name).collect();
89+
assert!(struct_names.contains(&&"Person".to_string()));
90+
assert!(struct_names.contains(&&"Address".to_string()));
91+
92+
// Find method chunks
93+
let method_chunks: Vec<_> = chunks
94+
.iter()
95+
.filter(|c| matches!(c.chunk_type, ChunkType::Method))
96+
.collect();
97+
assert_eq!(method_chunks.len(), 2);
98+
99+
let method_names: Vec<&String> = method_chunks.iter().map(|c| &c.name).collect();
100+
assert!(method_names.contains(&&"GetName".to_string()));
101+
assert!(method_names.contains(&&"GetFullAddress".to_string()));
102+
}
103+
104+
#[test]
105+
fn test_go_interface_extraction() {
106+
let temp_dir = TempDir::new().unwrap();
107+
let file_path = temp_dir.path().join("test.go");
108+
109+
let go_code = r#"package main
110+
111+
type Writer interface {
112+
Write([]byte) (int, error)
113+
}
114+
115+
type Reader interface {
116+
Read([]byte) (int, error)
117+
}
118+
119+
type ReadWriter interface {
120+
Reader
121+
Writer
122+
}
123+
124+
func process(rw ReadWriter) {
125+
// Implementation here
126+
}
127+
"#;
128+
fs::write(&file_path, go_code).unwrap();
129+
130+
let mut extractor = CodeExtractor::new().unwrap();
131+
let chunks = extractor
132+
.extract_chunks(temp_dir.path(), ExtractionOptions::default())
133+
.unwrap();
134+
135+
assert_eq!(chunks.len(), 4); // 3 interfaces + 1 function
136+
137+
// Find interface chunks
138+
let interface_chunks: Vec<_> = chunks
139+
.iter()
140+
.filter(|c| matches!(c.chunk_type, ChunkType::Interface))
141+
.collect();
142+
assert_eq!(interface_chunks.len(), 3);
143+
144+
let interface_names: Vec<&String> = interface_chunks.iter().map(|c| &c.name).collect();
145+
assert!(interface_names.contains(&&"Writer".to_string()));
146+
assert!(interface_names.contains(&&"Reader".to_string()));
147+
assert!(interface_names.contains(&&"ReadWriter".to_string()));
148+
149+
// Find function chunk
150+
let function_chunks: Vec<_> = chunks
151+
.iter()
152+
.filter(|c| matches!(c.chunk_type, ChunkType::Function))
153+
.collect();
154+
assert_eq!(function_chunks.len(), 1);
155+
assert_eq!(function_chunks[0].name, "process");
156+
}
157+
158+
#[test]
159+
fn test_go_const_var_type_alias_extraction() {
160+
let temp_dir = TempDir::new().unwrap();
161+
let file_path = temp_dir.path().join("test.go");
162+
163+
let go_code = r#"package main
164+
165+
import "errors"
166+
167+
// Const block test
168+
const (
169+
StatusOK = 200
170+
StatusNotFound = 404
171+
StatusError = 500
172+
)
173+
174+
// Single const
175+
const MaxRetries = 3
176+
177+
// Var block test
178+
var (
179+
ErrNotFound = errors.New("not found")
180+
ErrTimeout = errors.New("timeout")
181+
)
182+
183+
// Single var
184+
var GlobalCounter int
185+
186+
// Type alias tests
187+
type UserID int64
188+
type Handler func(string, string)
189+
type Point struct {
190+
X, Y int
191+
}
192+
193+
func main() {}
194+
"#;
195+
fs::write(&file_path, go_code).unwrap();
196+
197+
let mut extractor = CodeExtractor::new().unwrap();
198+
let chunks = extractor
199+
.extract_chunks(temp_dir.path(), ExtractionOptions::default())
200+
.unwrap();
201+
202+
// Should find: 2 const blocks + 2 var blocks + 2 type aliases + 1 function + 1 struct = 8 total
203+
assert_eq!(chunks.len(), 8);
204+
205+
// Find const chunks
206+
let const_chunks: Vec<_> = chunks
207+
.iter()
208+
.filter(|c| matches!(c.chunk_type, ChunkType::Const))
209+
.collect();
210+
assert!(
211+
const_chunks.len() >= 2,
212+
"Should find at least 2 const blocks"
213+
);
214+
215+
// Find var chunks
216+
let var_chunks: Vec<_> = chunks
217+
.iter()
218+
.filter(|c| matches!(c.chunk_type, ChunkType::Variable))
219+
.collect();
220+
assert!(var_chunks.len() >= 2, "Should find at least 2 var blocks");
221+
222+
// Find type alias chunks (should include UserID, Handler)
223+
let type_alias_chunks: Vec<_> = chunks
224+
.iter()
225+
.filter(|c| matches!(c.chunk_type, ChunkType::TypeAlias))
226+
.collect();
227+
assert!(
228+
type_alias_chunks.len() >= 2,
229+
"Should find at least 2 type aliases"
230+
);
231+
232+
let type_alias_names: Vec<&String> = type_alias_chunks.iter().map(|c| &c.name).collect();
233+
assert!(type_alias_names.contains(&&"UserID".to_string()));
234+
assert!(type_alias_names.contains(&&"Handler".to_string()));
235+
236+
// Verify we still find struct and function
237+
let struct_chunks: Vec<_> = chunks
238+
.iter()
239+
.filter(|c| matches!(c.chunk_type, ChunkType::Struct))
240+
.collect();
241+
assert_eq!(struct_chunks.len(), 1);
242+
assert_eq!(struct_chunks[0].name, "Point");
243+
244+
let function_chunks: Vec<_> = chunks
245+
.iter()
246+
.filter(|c| matches!(c.chunk_type, ChunkType::Function))
247+
.collect();
248+
assert!(!function_chunks.is_empty());
249+
250+
let function_names: Vec<&String> = function_chunks.iter().map(|c| &c.name).collect();
251+
assert!(function_names.contains(&&"main".to_string()));
252+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
use gittype::extractor::{CodeExtractor, ExtractionOptions, Language};
2+
use std::io::Write;
3+
use tempfile::NamedTempFile;
4+
5+
#[test]
6+
fn test_kotlin_class_extraction() {
7+
let kotlin_code = r#"
8+
class MainActivity : AppCompatActivity() {
9+
companion object {
10+
const val TAG = "MainActivity"
11+
12+
fun staticMethod(): String {
13+
return "Hello from static method"
14+
}
15+
}
16+
17+
private val name: String = "GitType"
18+
19+
fun greetUser(username: String): String {
20+
return "Hello, $username! Welcome to $name."
21+
}
22+
}
23+
24+
data class User(
25+
val id: Long,
26+
val name: String,
27+
val email: String
28+
) {
29+
fun getDisplayName(): String = "$name ($email)"
30+
}
31+
32+
object DatabaseHelper {
33+
fun connect(): Connection {
34+
return DriverManager.getConnection("jdbc:sqlite:app.db")
35+
}
36+
}
37+
"#;
38+
39+
let mut file = NamedTempFile::new().unwrap();
40+
file.write_all(kotlin_code.as_bytes()).unwrap();
41+
file.flush().unwrap();
42+
43+
let mut extractor = CodeExtractor::new().unwrap();
44+
let options = ExtractionOptions::default();
45+
let chunks = extractor
46+
.extract_from_file(file.path(), Language::Kotlin, &options)
47+
.unwrap();
48+
49+
let class_chunks: Vec<_> = chunks
50+
.iter()
51+
.filter(|chunk| chunk.name.contains("MainActivity") || chunk.name.contains("User"))
52+
.collect();
53+
assert!(
54+
!class_chunks.is_empty(),
55+
"Should extract classes MainActivity and User"
56+
);
57+
58+
let function_chunks: Vec<_> = chunks
59+
.iter()
60+
.filter(|chunk| {
61+
chunk.name.contains("greetUser")
62+
|| chunk.name.contains("getDisplayName")
63+
|| chunk.name.contains("staticMethod")
64+
|| chunk.name.contains("connect")
65+
})
66+
.collect();
67+
assert!(
68+
!function_chunks.is_empty(),
69+
"Should extract functions from classes and objects"
70+
);
71+
72+
let object_chunks: Vec<_> = chunks
73+
.iter()
74+
.filter(|chunk| chunk.name.contains("DatabaseHelper"))
75+
.collect();
76+
assert!(
77+
!object_chunks.is_empty(),
78+
"Should extract object declarations"
79+
);
80+
}

tests/integration/languages/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
pub mod go;
2+
pub mod kotlin;
3+
pub mod python;
4+
pub mod ruby;
5+
pub mod rust;
6+
pub mod swift;
7+
pub mod typescript;

0 commit comments

Comments
 (0)