1
+ use std:: fs:: File ;
2
+ use std:: io:: { Write , Read , BufRead } ;
3
+ use std:: path:: { Path , PathBuf } ;
4
+
5
+ use codeql_extractor:: extractor:: simple;
6
+ use flate2:: read:: GzDecoder ;
7
+ use tree_sitter_ql;
8
+
9
+
10
+
11
+ /// An very simple happy-path test.
12
+ /// We run the extractor using the tree-sitter-ql grammar and a single source file,
13
+ /// and check that we get a reasonable-looking trap file in the expected location.
14
+ #[ test]
15
+ fn simple_extractor ( ) {
16
+ let language = simple:: LanguageSpec {
17
+ prefix : "ql" ,
18
+ ts_language : tree_sitter_ql:: language ( ) ,
19
+ node_types : tree_sitter_ql:: NODE_TYPES ,
20
+ file_extensions : vec ! [ "qll" . into( ) ] ,
21
+ } ;
22
+
23
+ let root_dir = std:: env:: temp_dir ( ) . join ( format ! ( "codeql-extractor-{}" , rand:: random:: <u16 >( ) ) ) ;
24
+ std:: fs:: create_dir_all ( & root_dir) . unwrap ( ) ;
25
+
26
+ let trap_dir = create_dir ( & root_dir, "trap" ) ;
27
+ let source_archive_dir = create_dir ( & root_dir, "src" ) ;
28
+
29
+ // Create foo.qll source file
30
+ let foo_qll = {
31
+ let path = source_archive_dir. join ( "foo.qll" ) ;
32
+ let mut file = File :: create ( & path) . expect ( "Failed to create src/foo.qll" ) ;
33
+ file. write_all ( b"predicate p(int a) { a = 1 }" ) . expect ( "Failed to write to foo.qll" ) ;
34
+ PathBuf :: from ( path)
35
+ } ;
36
+
37
+ let file_list = {
38
+ let path = root_dir. join ( "files.txt" ) ;
39
+ let mut file = File :: create ( & path) . expect ( "Failed to create files.txt" ) ;
40
+ file. write_all ( foo_qll. as_path ( ) . display ( ) . to_string ( ) . as_bytes ( ) ) . expect ( "Failed to write to files.txt" ) ;
41
+ path
42
+ } ;
43
+
44
+ let extractor = simple:: Extractor {
45
+ prefix : "ql" . to_string ( ) ,
46
+ languages : vec ! [ language] ,
47
+ trap_dir,
48
+ source_archive_dir,
49
+ file_list,
50
+ } ;
51
+
52
+ // The extractor should run successfully
53
+ extractor. run ( ) . unwrap ( ) ;
54
+
55
+ // Check for the presence of $root/trap/$root/src/foo.qll
56
+ {
57
+ let root_dir_relative = {
58
+ let r = root_dir. as_path ( ) . display ( ) . to_string ( ) ;
59
+ r. strip_prefix ( "/" ) . unwrap ( ) . to_string ( )
60
+ } ;
61
+ let foo_qll_trap_gz = root_dir. join ( "trap" ) . join ( root_dir_relative) . join ( "src/foo.qll.trap.gz" ) ;
62
+ let mut decoder = GzDecoder :: new ( File :: open ( foo_qll_trap_gz) . expect ( "Failed to open foo.qll.trap.gz" ) ) ;
63
+ let mut first_line = [ 0 ; 31 ] ;
64
+ decoder. read_exact ( & mut first_line) . expect ( "Failed to read from foo.qll.trap.gz" ) ;
65
+ assert_eq ! ( first_line. as_slice( ) , b"// Auto-generated TRAP file for" ) ;
66
+ }
67
+ }
68
+
69
+ fn create_dir ( root : & Path , path : impl AsRef < Path > ) -> PathBuf {
70
+ let full_path = root. join ( path) ;
71
+ std:: fs:: create_dir_all ( & full_path) . expect ( "Failed to create directory" ) ;
72
+ full_path. into ( )
73
+ }
0 commit comments