Skip to content

Commit

Permalink
Add integration test for reading library
Browse files Browse the repository at this point in the history
  • Loading branch information
EPashkin committed May 18, 2018
1 parent 1825132 commit aa4f5bc
Show file tree
Hide file tree
Showing 14 changed files with 444 additions and 5 deletions.
13 changes: 12 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,22 @@ mod visitors;
mod writer;
mod xmlparser;

pub use analysis::run as analysis_run;
pub use analysis::class_hierarchy::run as class_hierarchy_run;
pub use analysis::namespaces::run as namespaces_run;
pub use analysis::run as analysis_run;
pub use analysis::symbols::run as symbols_run;
pub use codegen::generate as codegen_generate;
pub use config::{Config, WorkMode};
pub use env::Env;
pub use library::Library;

pub mod tests_export {
pub use config::gobjects::{GObject, GObjects};
pub use traits::*;
pub use version::Version;

pub mod library {
pub use library::*;
pub use parser::EMPTY_CTYPE;
}
}
21 changes: 18 additions & 3 deletions src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::io::Read;
use std::mem::replace;
use std::path::{Path, PathBuf};
use std::str::FromStr;
Expand All @@ -6,7 +7,7 @@ use library::*;
use version::Version;
use xmlparser::{Element, XmlParser};

const EMPTY_CTYPE: &str = "/*EMPTY*/";
pub const EMPTY_CTYPE: &str = "/*EMPTY*/";

pub fn is_empty_c_type(c_type: &str) -> bool {
c_type == EMPTY_CTYPE
Expand All @@ -23,6 +24,16 @@ impl Library {
})
}

pub fn read_reader<R: Read>(&mut self, reader: R) -> Result<(), String> {
let dir = Path::new("read_reader_not_implement_include");
let mut p = XmlParser::new(reader)?;
p.document(|p, _| {
p.element_with_name("repository", |parser, _elem| {
self.read_repository(dir, parser)
})
})
}

fn read_repository(&mut self, dir: &Path, parser: &mut XmlParser) -> Result<(), String> {
let mut package = None;
let mut includes = Vec::new();
Expand All @@ -48,8 +59,12 @@ impl Library {
}
Ok(())
}
"namespace" => self.read_namespace(parser, elem, package.take(),
replace(&mut includes, Vec::new())),
"namespace" => self.read_namespace(
parser,
elem,
package.take(),
replace(&mut includes, Vec::new()),
),
_ => Err(parser.unexpected_element(elem)),
})?;
Ok(())
Expand Down
1 change: 0 additions & 1 deletion src/xmlparser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ impl<'a> XmlParser<'a> {
}
}

#[cfg(test)]
pub fn new<'r, R: 'r + Read>(read: R) -> Result<XmlParser<'r>, String> {
Ok(XmlParser {
parser: EventReader::new(Box::new(read)),
Expand Down
194 changes: 194 additions & 0 deletions tests/read_library.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
//! This test module contains tests that use files read_library\*.gir for checking library load
extern crate libgir as gir;

mod test_util;

use std::fs::File;
use std::io::{self, Read};
use std::path::Path;

use gir::tests_export::*;
use test_util::*;

fn read_library<P: AsRef<Path>>(filename: P) -> Result<(library::Library), io::Error> {
let full_name = Path::new("tests")
.join("read_library")
.join(filename.as_ref());
let cfg = create_default_config();
let mut library = library::Library::new(&cfg.library_name);
let (f, _) = read_parameterized(full_name)?;
library.read_reader(f).unwrap();
Ok(library)
}

#[test]
fn load_normal() {
let cfg = create_default_config();
let mut library = library::Library::new(&cfg.library_name);

let f = File::open("tests/read_library/normal.gir").unwrap();
library.read_reader(f).unwrap();
assert!(library.find_type(1, "TimeSpan").is_some());
}

#[test]
fn read_mode_default() {
let (mut f, _) = read_parameterized("tests/read_library/normal.gir").unwrap();
let mut buffer = vec![0u8; 6];
assert_eq!(f.read(&mut buffer).unwrap(), 6);
let str = String::from_utf8_lossy(&buffer);
assert_eq!(str, "<?xml ");
}

#[test]
fn read_mode_full() {
let (mut f, _) = read_parameterized("tests/read_library/mode_full.gir").unwrap();
let mut buffer = vec![0u8; 6];
assert_eq!(f.read(&mut buffer).unwrap(), 6);
let str = String::from_utf8_lossy(&buffer);
assert_eq!(str, "<?xml ");
}

#[test]
fn read_mode_object() {
let (mut f, _) = read_parameterized("tests/read_library/mode_object.gir").unwrap();
let mut buffer = vec![0u8; 6];
assert_eq!(f.read(&mut buffer).unwrap(), 6);
let str = String::from_utf8_lossy(&buffer);
assert_eq!(str, "<?xml ");
}

#[test]
fn load_alias() {
let library = read_library("alias.gir").unwrap();
let a: &library::Alias = get_type(&library, "TimeSpan");
assert_eq!(a.c_identifier, "TTimeSpan");
assert_eq!(a.target_c_type, "gint64");
assert_eq!(a.typ.full_name(&library), "*.Int64");
}

#[test]
fn load_bitfield() {
let library = read_library("bitfield.gir").unwrap();
let b: &library::Bitfield = get_type(&library, "AsciiType");
assert_eq!(b.c_type, "TAsciiType");
let m = &b.members[0];
assert_eq!(m.name, "alnum");
assert_eq!(m.c_identifier, "T_ASCII_ALNUM");
assert_eq!(m.value, "1");
let m = &b.members[1];
assert_eq!(m.name, "alpha");
assert_eq!(m.c_identifier, "T_ASCII_ALPHA");
assert_eq!(m.value, "2");
}

#[test]
fn load_class() {
let library = read_library("class.gir").unwrap();
let typ_object = library.find_type(0, "GObject.Object").unwrap();
let typ_app_info = library.find_type(0, "Tst.AppInfo").unwrap();
let typ_variant = library.find_type(0, "GLib.Variant").unwrap();
let c: &library::Class = get_type(&library, "AppLaunchContext");
assert_eq!(c.c_type, "GAppLaunchContext");
assert_eq!(c.type_struct, Some("AppLaunchContextClass".into()));
assert_eq!(c.glib_get_type, "g_app_launch_context_get_type");
assert_eq!(c.parent, Some(typ_object));
assert_eq!(c.version, None);
let f = &c.functions[0];
assert_eq!(f.name, "new");
assert_eq!(f.c_identifier, Some("g_app_launch_context_new".into()));
assert_eq!(f.kind, library::FunctionKind::Constructor);
assert_eq!(f.throws, false);
assert_eq!(f.version, None);
let f = &c.functions[1];
assert_eq!(f.name, "get_environment");
assert_eq!(
f.c_identifier,
Some("g_app_launch_context_get_environment".into())
);
assert_eq!(f.kind, library::FunctionKind::Method);
assert_eq!(f.throws, false);
assert_eq!(f.version, Some(Version::Full(2, 32, 0)));
let f = &c.fields[0];
assert_eq!(f.name, "parent_instance");
assert_eq!(f.c_type, Some("GObject".into()));
assert_eq!(f.typ, typ_object);
assert_eq!(f.private, false);
let s = &c.signals[0];
assert_eq!(s.name, "launched");
assert_eq!(s.is_action, false);
assert_eq!(s.version, Some(Version::Full(2, 36, 0)));
let p = &s.parameters[0];
assert_eq!(p.name, "info");
assert_eq!(p.c_type, library::EMPTY_CTYPE);
assert_eq!(p.typ, typ_app_info);
assert_eq!(p.transfer, library::Transfer::None);
let p = &s.parameters[1];
assert_eq!(p.name, "platform_data");
assert_eq!(p.c_type, library::EMPTY_CTYPE);
assert_eq!(p.typ, typ_variant);
assert_eq!(p.transfer, library::Transfer::None);
let p = &s.ret;
assert_eq!(p.name, "");
assert_eq!(p.c_type, "void");
assert_eq!(p.typ.full_name(&library), "*.None");
assert_eq!(p.transfer, library::Transfer::None);
}

#[test]
fn load_constant() {
let library = read_library("constant.gir").unwrap();
let ns = library.namespace(library::MAIN_NAMESPACE);
let c = &ns.constants[0];
assert_eq!(c.name, "ANALYZER_ANALYZING");
assert_eq!(c.c_identifier, "T_ANALYZER_ANALYZING");
assert_eq!(c.c_type, "gint");
assert_eq!(c.typ.full_name(&library), "*.Int");
assert_eq!(c.value, "1");
}

#[test]
fn load_enumeration() {
let library = read_library("enumeration.gir").unwrap();
let e: &library::Enumeration = get_type(&library, "BookmarkFileError");
assert_eq!(e.c_type, "TBookmarkFileError");
assert_eq!(e.error_domain, Some("t-bookmark-file-error-quark".into()));
let m = &e.members[0];
assert_eq!(m.name, "invalid_uri");
assert_eq!(m.c_identifier, "T_BOOKMARK_FILE_ERROR_INVALID_URI");
assert_eq!(m.value, "0");
let m = &e.members[1];
assert_eq!(m.name, "invalid_value");
assert_eq!(m.c_identifier, "T_BOOKMARK_FILE_ERROR_INVALID_VALUE");
assert_eq!(m.value, "1");
}

#[test]
fn load_function() {
let library = read_library("function.gir").unwrap();
let ns = library.namespace(library::MAIN_NAMESPACE);
let f = &ns.functions[0];
assert_eq!(f.name, "access");
assert_eq!(f.c_identifier, Some("t_access".into()));
assert_eq!(f.kind, library::FunctionKind::Global);
assert_eq!(f.throws, false);
assert_eq!(f.version, Some(Version::Full(2, 8, 0)));
let p = &f.parameters[0];
assert_eq!(p.name, "filename");
assert_eq!(p.c_type, "const gchar*");
assert_eq!(p.typ.full_name(&library), "*.Filename");
assert_eq!(p.transfer, library::Transfer::Full);
let p = &f.parameters[1];
assert_eq!(p.name, "mode");
assert_eq!(p.c_type, "int");
assert_eq!(p.typ.full_name(&library), "*.Int");
assert_eq!(p.transfer, library::Transfer::None);
let p = &f.ret;
assert_eq!(p.name, "");
assert_eq!(p.c_type, "int");
assert_eq!(p.typ.full_name(&library), "*.Int");
assert_eq!(p.transfer, library::Transfer::None);
}

//TODO: interface, record, union, callback
4 changes: 4 additions & 0 deletions tests/read_library/alias.gir
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!--mode:object-->
<alias name="TimeSpan" c:type="TTimeSpan">
<type name="gint64" c:type="gint64"/>
</alias>
7 changes: 7 additions & 0 deletions tests/read_library/bitfield.gir
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!--mode:object-->
<bitfield name="AsciiType" c:type="TAsciiType">
<member name="alnum" value="1" c:identifier="T_ASCII_ALNUM">
</member>
<member name="alpha" value="2" c:identifier="T_ASCII_ALPHA">
</member>
</bitfield>
54 changes: 54 additions & 0 deletions tests/read_library/class.gir
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!--mode:object-->
<class name="AppLaunchContext" c:symbol-prefix="app_launch_context" c:type="GAppLaunchContext" parent="GObject.Object" glib:type-name="GAppLaunchContext" glib:get-type="g_app_launch_context_get_type" glib:type-struct="AppLaunchContextClass">
<constructor name="new" c:identifier="g_app_launch_context_new">
<return-value transfer-ownership="full">
<type name="AppLaunchContext" c:type="GAppLaunchContext*"/>
</return-value>
</constructor>
<virtual-method name="get_display" invoker="get_display">
<return-value transfer-ownership="full">
<type name="utf8" c:type="char*"/>
</return-value>
<parameters>
<instance-parameter name="context" transfer-ownership="none">
<type name="AppLaunchContext" c:type="GAppLaunchContext*"/>
</instance-parameter>
<parameter name="info" transfer-ownership="none">
<type name="AppInfo" c:type="GAppInfo*"/>
</parameter>
<parameter name="files" transfer-ownership="none">
<type name="GLib.List" c:type="GList*">
<type name="File"/>
</type>
</parameter>
</parameters>
</virtual-method>
<method name="get_environment" c:identifier="g_app_launch_context_get_environment" version="2.32">
<return-value transfer-ownership="full">
<array c:type="char**">
<type name="filename"/>
</array>
</return-value>
<parameters>
<instance-parameter name="context" transfer-ownership="none">
<type name="AppLaunchContext" c:type="GAppLaunchContext*"/>
</instance-parameter>
</parameters>
</method>
<field name="parent_instance">
<type name="GObject.Object" c:type="GObject"/>
</field>
<glib:signal name="launched" when="last" version="2.36">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
</return-value>
<parameters>
<parameter name="info" transfer-ownership="none">
<type name="AppInfo"/>
</parameter>
<parameter name="platform_data" transfer-ownership="none">
<type name="GLib.Variant"/>
</parameter>
</parameters>
</glib:signal>
</class>
4 changes: 4 additions & 0 deletions tests/read_library/constant.gir
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!--mode:object-->
<constant name="ANALYZER_ANALYZING" value="1" c:type="T_ANALYZER_ANALYZING">
<type name="gint" c:type="gint"/>
</constant>
8 changes: 8 additions & 0 deletions tests/read_library/enumeration.gir
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!--mode:object-->
<enumeration name="BookmarkFileError" c:type="TBookmarkFileError" glib:error-domain="t-bookmark-file-error-quark">
<doc xml:space="preserve">Error codes returned by bookmark file parsing.</doc>
<member name="invalid_uri" value="0" c:identifier="T_BOOKMARK_FILE_ERROR_INVALID_URI">
</member>
<member name="invalid_value" value="1" c:identifier="T_BOOKMARK_FILE_ERROR_INVALID_VALUE">
</member>
</enumeration>
14 changes: 14 additions & 0 deletions tests/read_library/function.gir
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!--mode:object-->
<function name="access" c:identifier="t_access" version="2.8">
<return-value transfer-ownership="none">
<type name="gint" c:type="int"/>
</return-value>
<parameters>
<parameter name="filename" transfer-ownership="full">
<type name="filename" c:type="const gchar*"/>
</parameter>
<parameter name="mode" transfer-ownership="none">
<type name="gint" c:type="int"/>
</parameter>
</parameters>
</function>
10 changes: 10 additions & 0 deletions tests/read_library/mode_full.gir
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!--mode:full-->
<?xml version="1.0"?>
<repository xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0" version="1.2">
<package name="tst-1.0"/>
<namespace name="Tst" version="1.0" c:identifier-prefixes="T" c:symbol-prefixes="t,tst">
<alias name="TimeSpan" c:type="TTimeSpan">
<type name="gint64" c:type="gint64"/>
</alias>
</namespace>
</repository>
4 changes: 4 additions & 0 deletions tests/read_library/mode_object.gir
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!--mode:object-->
<alias name="TimeSpan" c:type="TTimeSpan">
<type name="gint64" c:type="gint64"/>
</alias>
9 changes: 9 additions & 0 deletions tests/read_library/normal.gir
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<repository xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0" version="1.2">
<package name="tst-1.0"/>
<namespace name="Tst" version="1.0" c:identifier-prefixes="T" c:symbol-prefixes="t,tst">
<alias name="TimeSpan" c:type="TTimeSpan">
<type name="gint64" c:type="gint64"/>
</alias>
</namespace>
</repository>
Loading

0 comments on commit aa4f5bc

Please sign in to comment.