1pub mod include;
2pub mod position;
3pub mod shader;
4pub mod shader_error;
5pub mod symbols;
6pub mod validator;
7
8#[cfg(test)]
9mod tests {
10 use std::{
11 cell::RefCell,
12 collections::HashMap,
13 path::{Path, PathBuf},
14 rc::Rc,
15 };
16
17 use crate::{
18 include::{canonicalize, IncludeHandler},
19 shader::{ShaderParams, ShadingLanguage},
20 symbols::{shader_module_parser::ShaderModuleParser, symbol_provider::SymbolProvider},
21 validator::validator::Validator,
22 };
23
24 fn validate_include(path: &Path) -> bool {
25 let file_path = Path::new("./test/hlsl/dontcare.hlsl");
26 let mut include_handler = IncludeHandler::main(
27 file_path,
28 vec![],
29 HashMap::from([
30 (
31 PathBuf::from("/Packages"),
32 PathBuf::from("./test/hlsl/inc0/inc1"),
33 ),
34 (
35 PathBuf::from("Packages"),
36 PathBuf::from("./test/hlsl/inc0/inc1"),
37 ),
38 (
39 PathBuf::from("Using\\Backslashes"),
40 PathBuf::from("./test/hlsl/inc0/inc1"),
41 ),
42 ]),
43 );
44 include_handler.search_path_in_includes(path).is_some()
45 }
46
47 #[test]
48 fn test_virtual_path() {
49 assert!(
50 validate_include(Path::new("/Packages/level1.hlsl")),
51 "Virtual path with prefix failed."
52 );
53 assert!(
54 validate_include(Path::new("Packages/level1.hlsl")),
55 "Virtual path without prefix failed."
56 );
57 #[cfg(target_os = "windows")] assert!(
59 validate_include(Path::new("Using/Backslashes/level1.hlsl")),
60 "Virtual path with backslash failed."
61 );
62 }
63
64 #[test]
65 fn test_directory_stack() {
66 let file_path = Path::new("./test/hlsl/include-level.hlsl");
67 let mut include_handler = IncludeHandler::main(file_path, vec![], HashMap::new());
68 let absolute_level0 =
69 include_handler.search_path_in_includes(Path::new("./inc0/level0.hlsl"));
70 assert!(absolute_level0.is_some());
71 include_handler.push_directory_stack(&absolute_level0.unwrap());
72 let absolute_level1 =
73 include_handler.search_path_in_includes(Path::new("./inc1/level1.hlsl"));
74 assert!(absolute_level1.is_some());
75 }
76
77 #[test]
78 fn test_stack_overflow() {
79 let file_path = Path::new("./test/hlsl/stack-overflow.hlsl");
81 let mut shader_module_parser =
82 ShaderModuleParser::from_shading_language(ShadingLanguage::Hlsl);
83 let symbol_provider = SymbolProvider::from_shading_language(ShadingLanguage::Hlsl);
84 let shader_module = shader_module_parser
85 .create_module(file_path, &std::fs::read_to_string(file_path).unwrap())
86 .unwrap();
87 println!("Testing symbol overflow");
88 let mut depth = 0;
89 match symbol_provider.query_symbols(
90 &shader_module,
91 ShaderParams::default(),
92 &mut |include| {
93 depth += 1;
94 println!(
95 "Including {} (depth {})",
96 include.get_absolute_path().display(),
97 depth
98 );
99 Ok(Some(Rc::new(RefCell::new(
100 shader_module_parser
101 .create_module(
102 &include.get_absolute_path(),
103 &std::fs::read_to_string(&include.get_absolute_path()).unwrap(),
104 )
105 .unwrap(),
106 ))))
107 },
108 None,
109 ) {
110 Ok(_) => {}
111 Err(err) => panic!("Failed to query symbols: {}", err),
112 }
113 println!("Testing validation overflow");
114 let validator = Validator::from_shading_language(ShadingLanguage::Hlsl);
115 match validator.validate_shader(
116 &shader_module.content,
117 file_path,
118 &ShaderParams::default(),
119 &mut |path| Some(std::fs::read_to_string(path).unwrap()),
120 ) {
121 Ok(diagnostics) => assert!(
122 !diagnostics.is_empty(),
123 "Diagnostics are empty but should not be."
124 ),
125 Err(err) => panic!("Failed to validate shader: {}", err),
126 }
127 }
128 #[test]
129 fn test_canonicalize_parent() {
130 if cfg!(target_os = "windows") {
131 let path = canonicalize(Path::new("D:\\test\\data")).unwrap();
132 assert!(path == Path::new("D:\\test\\data"));
133 assert!(path.parent().unwrap() == Path::new("D:\\test"));
134 } else {
135 let path = canonicalize(Path::new("/test/data")).unwrap();
136 assert!(path == Path::new("/test/data"));
137 assert!(path.parent().unwrap() == Path::new("/test"));
138 }
139 }
140 #[test]
141 fn test_canonicalize_join() {
142 if cfg!(target_os = "windows") {
143 let path = canonicalize(Path::new("D:\\test")).unwrap();
144 assert!(path == Path::new("D:\\test"));
145 assert!(path.join("data") == Path::new("D:\\test\\data"));
146 } else {
147 let path = canonicalize(Path::new("/test")).unwrap();
148 assert!(path == Path::new("/test"));
149 assert!(path.join("data") == Path::new("/test/data"));
150 }
151 }
152}