Commit c98318d2 authored by mredlek's avatar mredlek

Fail on messages by the glib-system during object instantiation

parent ef6c7c41
......@@ -3,3 +3,5 @@ pub use glib;
pub use glib_sys;
pub use gobject_sys;
pub use libc;
pub mod testhelper;
/// ! This module contains code that is used in the generated unit test for testing the type at
/// runtime.
use ::glib_sys::{gpointer, GDestroyNotify};
use ::libc::{c_char, c_int, c_void, size_t};
use ::std::ptr;
use std::ffi::CString;
#[repr(C)]
struct GLogField {
name: *const c_char,
value: gpointer,
size: size_t,
}
// type GLogFunc = unsafe extern "C" fn(domain: *const c_char, flags: c_int, message: *const c_char,
// user: gpointer);
type GLogWriterFunc =
unsafe extern "C" fn(flags: c_int, fields: *const GLogField, nr_fields: size_t, user: gpointer)
-> c_int;
extern "C" {
// fn g_log_set_always_fatal(flags: ::libc::c_int) -> ::libc::c_int;
fn g_log_writer_default(
flags: c_int,
fields: *const GLogField,
nr_fields: size_t,
user: gpointer,
) -> c_int;
// fn g_log_set_handler(domain: *const c_char, log_levels: c_int,
// callback: GLogFunc,
// user: *const c_void) -> c_uint;
fn g_log_set_writer_func(
func: GLogWriterFunc,
user_data: gpointer,
user_data_free: GDestroyNotify,
);
fn g_log_writer_format_fields(
log_level: c_int,
fields: *const GLogField,
n_fields: size_t,
use_color: c_char,
) -> *mut c_char;
}
pub struct PanicOnMessage {
msg: Box<Vec<String>>,
}
impl PanicOnMessage {
pub fn new() -> Self {
let mut this = PanicOnMessage {
msg: Box::new(Vec::new()),
};
unsafe {
g_log_set_writer_func(
Self::on_struct_message_report,
(&mut *this.msg as *mut Vec<String>) as *mut c_void,
None,
)
}
this
}
#[allow(dead_code)]
pub fn clear(&mut self) -> Vec<String> {
let mut res = Vec::new();
::std::mem::swap(&mut *self.msg, &mut res);
res
}
unsafe extern "C" fn on_struct_message_report(
flags: c_int,
fields: *const GLogField,
nr_fields: size_t,
this: gpointer,
) -> c_int {
let this = &mut *(this as *mut Vec<String>);
let msg = CString::from_raw(g_log_writer_format_fields(flags, fields, nr_fields, 0i8));
if let Ok(msg) = msg.into_string() {
this.push(msg);
} else {
eprintln!("Unable to convert to string");
}
g_log_writer_default(flags, fields, nr_fields, ptr::null_mut())
}
}
impl Drop for PanicOnMessage {
fn drop(&mut self) {
// Make sure that the user data is destroyed and not used again
unsafe {
g_log_set_writer_func(g_log_writer_default, ptr::null_mut(), None);
}
if self.msg.len() > 0 {
panic!(
"The following messages are received from the glib:{}",
self.msg.join("")
);
}
}
}
//! This file contains the instantion of all the data that is instantiated once
//! and stored in a static variable
use gen::Test;
use crate::gen::boilerplate;
use crate::gen::boilerplateext::BoilerplateExt;
use crate::gen::Test;
use crate::hir::{Override, OverrideItem};
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
......
/// ! This file has code to generate a test to test the generated gobject type.
/// ! The test can find missing parents or other user error which
/// ! can't be collected during codegen
use gen::boilerplate;
use crate::gen::boilerplate;
use proc_macro2::{Ident, TokenStream};
use quote::ToTokens;
use quote::{quote, ToTokens};
use std::marker::PhantomData;
pub struct Test<'lt, 'ast: 'lt, Boilerplate: boilerplate::Boilerplate<'ast> + 'lt> {
......@@ -42,11 +42,20 @@ impl<'lt, 'ast: 'lt, Boilerplate: boilerplate::Boilerplate<'ast>> Test<'lt, 'ast
}
});
let name_instance = &self.boilerplate.names().instance();
let create_type = if self.boilerplate.fundamental_type() == ::glib::Type::BaseObject {
quote! { #name_instance::new(); }
} else {
TokenStream::new()
};
quote! {
#[test]
fn #test_get_type_fn_name()
{
use glib::Type;
let _panic_on_message = ::gobject_class::testhelper::PanicOnMessage::new();
use ::gobject_class::glib::Type;
//Test
let mut parents = vec![ Type::BaseObject #(, <#ancestors as ::glib::types::StaticType>::static_type())* ];
......@@ -64,12 +73,14 @@ impl<'lt, 'ast: 'lt, Boilerplate: boilerplate::Boilerplate<'ast>> Test<'lt, 'ast
current = <#name_instance as ::gobject_class::glib::types::StaticType>::static_type();
for interface in current.interfaces() {
if let Some(pos) = interfaces.iter().position(|x: &::glib::Type| x == &interface) {
if let Some(pos) = interfaces.iter().position(|x: &::gobject_class::glib::Type| x == &interface) {
interfaces.swap_remove(pos);
} else if interface != ::glib::Type::BaseInterface {
} else if interface != ::gobject_class::glib::Type::BaseInterface {
panic!("Unregistered interface \"{}\"", current.name());
}
}
#create_type
}
}
}
......
#![cfg(any(not(feature = "single-test"), feature = "single-test-memory-layout"))]
#![deny(warnings)]
//#![deny(warnings)]
extern crate gobject_class;
extern crate gobject_gen;
......@@ -65,6 +65,9 @@ gobject_gen! {
impl ThirteenSlots {
reserve_slots(10)
}
impl ThreeSlots for ThirteenSlots {}
impl TwoSlots for ThirteenSlots {}
}
fn assert_n_slots_bigger_than_gobject_class<T>(n: usize)
......
......@@ -33,7 +33,7 @@ gobject_gen! {
}
set(&self, value: T) {
let mut private = self.get_priv();
let private = self.get_priv();
private.p.set(value);
}
}
......@@ -45,7 +45,7 @@ gobject_gen! {
}
set(&self, value: T) {
let mut private = self.get_priv();
let private = self.get_priv();
private.p2.set(value);
}
}
......
use ::glib_sys::{gpointer, GDestroyNotify};
/// ! This module contains the code that can be reused in all tests in this directory
use ::glib_sys::{gpointer, GDestroyNotify};
use ::libc::{c_char, c_int, c_void, size_t};
use ::std::ptr;
use std::ffi::CString;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment