tests: Executable for testing layouts
This commit is contained in:
		@ -1,77 +1,10 @@
 | 
				
			|||||||
extern crate rs;
 | 
					extern crate rs;
 | 
				
			||||||
extern crate xkbcommon;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use rs::tests::check_builtin_layout;
 | 
				
			||||||
use std::env;
 | 
					use std::env;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use rs::data::Layout;
 | 
					 | 
				
			||||||
use xkbcommon::xkb;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use rs::util::WarningHandler;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub struct CountAndPrint(u32);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WarningHandler for CountAndPrint {
 | 
					 | 
				
			||||||
    fn handle(&mut self, warning: &str) {
 | 
					 | 
				
			||||||
        self.0 = self.0 + 1;
 | 
					 | 
				
			||||||
        println!("{}", warning);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl CountAndPrint {
 | 
					 | 
				
			||||||
    fn new() -> CountAndPrint {
 | 
					 | 
				
			||||||
        CountAndPrint(0)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn check_layout(name: &str) {
 | 
					 | 
				
			||||||
    let handler = CountAndPrint::new();
 | 
					 | 
				
			||||||
    let layout = Layout::from_resource(name).expect("Invalid layout file");
 | 
					 | 
				
			||||||
    let (layout, handler) = layout.build(handler);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if handler.0 > 0 {
 | 
					 | 
				
			||||||
        println!("{} mistakes in layout", handler.0)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let layout = layout.expect("layout broken");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    let keymap_str = layout.keymap_str
 | 
					 | 
				
			||||||
        .clone()
 | 
					 | 
				
			||||||
        .into_string().expect("Failed to decode keymap string");
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    let keymap = xkb::Keymap::new_from_string(
 | 
					 | 
				
			||||||
        &context,
 | 
					 | 
				
			||||||
        keymap_str.clone(),
 | 
					 | 
				
			||||||
        xkb::KEYMAP_FORMAT_TEXT_V1,
 | 
					 | 
				
			||||||
        xkb::KEYMAP_COMPILE_NO_FLAGS,
 | 
					 | 
				
			||||||
    ).expect("Failed to create keymap");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let state = xkb::State::new(&keymap);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    // "Press" each button with keysyms
 | 
					 | 
				
			||||||
    for view in layout.views.values() {
 | 
					 | 
				
			||||||
        for row in &view.rows {
 | 
					 | 
				
			||||||
            for button in &row.buttons {
 | 
					 | 
				
			||||||
                let keystate = button.state.borrow();
 | 
					 | 
				
			||||||
                for keycode in &keystate.keycodes {
 | 
					 | 
				
			||||||
                    match state.key_get_one_sym(*keycode) {
 | 
					 | 
				
			||||||
                        xkb::KEY_NoSymbol => {
 | 
					 | 
				
			||||||
                            eprintln!("{}", keymap_str);
 | 
					 | 
				
			||||||
                            panic!("Keysym {} on key {:?} can't be resolved", keycode, button.name);
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        _ => {},
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if handler.0 > 0 {
 | 
					 | 
				
			||||||
        panic!("Layout contains mistakes");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn main() -> () {
 | 
					fn main() -> () {
 | 
				
			||||||
    check_layout(env::args().nth(1).expect("No argument given").as_str());
 | 
					    check_builtin_layout(
 | 
				
			||||||
 | 
					        env::args().nth(1).expect("No argument given").as_str()
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								src/bin/test_layout.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/bin/test_layout.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					extern crate rs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use rs::tests::check_layout_file;
 | 
				
			||||||
 | 
					use std::env;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() -> () {
 | 
				
			||||||
 | 
					    check_layout_file(env::args().nth(1).expect("No argument given").as_str());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -305,7 +305,7 @@ impl Layout {
 | 
				
			|||||||
                    .map_err(LoadError::BadResource)
 | 
					                    .map_err(LoadError::BadResource)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn from_file(path: PathBuf) -> Result<Layout, Error> {
 | 
					    pub fn from_file(path: PathBuf) -> Result<Layout, Error> {
 | 
				
			||||||
        let infile = BufReader::new(
 | 
					        let infile = BufReader::new(
 | 
				
			||||||
            fs::OpenOptions::new()
 | 
					            fs::OpenOptions::new()
 | 
				
			||||||
                .read(true)
 | 
					                .read(true)
 | 
				
			||||||
 | 
				
			|||||||
@ -24,5 +24,6 @@ mod outputs;
 | 
				
			|||||||
mod popover;
 | 
					mod popover;
 | 
				
			||||||
mod resources;
 | 
					mod resources;
 | 
				
			||||||
mod submission;
 | 
					mod submission;
 | 
				
			||||||
 | 
					pub mod tests;
 | 
				
			||||||
pub mod util;
 | 
					pub mod util;
 | 
				
			||||||
mod xdg;
 | 
					mod xdg;
 | 
				
			||||||
 | 
				
			|||||||
@ -58,7 +58,7 @@ rslibs = custom_target(
 | 
				
			|||||||
    output: ['librs.a'],
 | 
					    output: ['librs.a'],
 | 
				
			||||||
    install: false,
 | 
					    install: false,
 | 
				
			||||||
    console: true,
 | 
					    console: true,
 | 
				
			||||||
    command: [cargo_script, '@OUTPUT@', 'build']
 | 
					    command: [cargo_script, '@OUTPUT@', 'build', '--lib']
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
build_rstests = custom_target(
 | 
					build_rstests = custom_target(
 | 
				
			||||||
@ -124,3 +124,13 @@ squeekboard = executable('squeekboard-real',
 | 
				
			|||||||
    '-DEEKBOARD_COMPILATION=1',
 | 
					    '-DEEKBOARD_COMPILATION=1',
 | 
				
			||||||
    '-DEEK_COMPILATION=1'],
 | 
					    '-DEEK_COMPILATION=1'],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_layout = custom_target('squeekboard_test_layout',
 | 
				
			||||||
 | 
					    build_by_default: true,
 | 
				
			||||||
 | 
					    # meson doesn't track all inputs, cargo does
 | 
				
			||||||
 | 
					    build_always_stale: true,
 | 
				
			||||||
 | 
					    output: ['test_layout'],
 | 
				
			||||||
 | 
					    console: true,
 | 
				
			||||||
 | 
					    command: [cargo_script, '@OUTPUT@', 'build', '--bin', 'test_layout'],
 | 
				
			||||||
 | 
					    install_dir: bindir,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										78
									
								
								src/tests.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/tests.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					/*! Testing functionality */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use ::data::Layout;
 | 
				
			||||||
 | 
					use xkbcommon::xkb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use ::util::WarningHandler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct CountAndPrint(u32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl WarningHandler for CountAndPrint {
 | 
				
			||||||
 | 
					    fn handle(&mut self, warning: &str) {
 | 
				
			||||||
 | 
					        self.0 = self.0 + 1;
 | 
				
			||||||
 | 
					        println!("{}", warning);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl CountAndPrint {
 | 
				
			||||||
 | 
					    fn new() -> CountAndPrint {
 | 
				
			||||||
 | 
					        CountAndPrint(0)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn check_builtin_layout(name: &str) {
 | 
				
			||||||
 | 
					    check_layout(Layout::from_resource(name).expect("Invalid layout data"))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn check_layout_file(path: &str) {
 | 
				
			||||||
 | 
					    check_layout(Layout::from_file(path.into()).expect("Invalid layout file"))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn check_layout(layout: Layout) {
 | 
				
			||||||
 | 
					    let handler = CountAndPrint::new();
 | 
				
			||||||
 | 
					    let (layout, handler) = layout.build(handler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if handler.0 > 0 {
 | 
				
			||||||
 | 
					        println!("{} mistakes in layout", handler.0)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let layout = layout.expect("layout broken");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    let keymap_str = layout.keymap_str
 | 
				
			||||||
 | 
					        .clone()
 | 
				
			||||||
 | 
					        .into_string().expect("Failed to decode keymap string");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    let keymap = xkb::Keymap::new_from_string(
 | 
				
			||||||
 | 
					        &context,
 | 
				
			||||||
 | 
					        keymap_str.clone(),
 | 
				
			||||||
 | 
					        xkb::KEYMAP_FORMAT_TEXT_V1,
 | 
				
			||||||
 | 
					        xkb::KEYMAP_COMPILE_NO_FLAGS,
 | 
				
			||||||
 | 
					    ).expect("Failed to create keymap");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let state = xkb::State::new(&keymap);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // "Press" each button with keysyms
 | 
				
			||||||
 | 
					    for view in layout.views.values() {
 | 
				
			||||||
 | 
					        for row in &view.rows {
 | 
				
			||||||
 | 
					            for button in &row.buttons {
 | 
				
			||||||
 | 
					                let keystate = button.state.borrow();
 | 
				
			||||||
 | 
					                for keycode in &keystate.keycodes {
 | 
				
			||||||
 | 
					                    match state.key_get_one_sym(*keycode) {
 | 
				
			||||||
 | 
					                        xkb::KEY_NoSymbol => {
 | 
				
			||||||
 | 
					                            eprintln!("{}", keymap_str);
 | 
				
			||||||
 | 
					                            panic!("Keysym {} on key {:?} can't be resolved", keycode, button.name);
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        _ => {},
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if handler.0 > 0 {
 | 
				
			||||||
 | 
					        panic!("Layout contains mistakes");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user