Skip to content

Commit aa4f5bc

Browse files
committed
Add integration test for reading library
1 parent 1825132 commit aa4f5bc

14 files changed

+444
-5
lines changed

src/lib.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,22 @@ mod visitors;
3838
mod writer;
3939
mod xmlparser;
4040

41-
pub use analysis::run as analysis_run;
4241
pub use analysis::class_hierarchy::run as class_hierarchy_run;
4342
pub use analysis::namespaces::run as namespaces_run;
43+
pub use analysis::run as analysis_run;
4444
pub use analysis::symbols::run as symbols_run;
4545
pub use codegen::generate as codegen_generate;
4646
pub use config::{Config, WorkMode};
4747
pub use env::Env;
4848
pub use library::Library;
49+
50+
pub mod tests_export {
51+
pub use config::gobjects::{GObject, GObjects};
52+
pub use traits::*;
53+
pub use version::Version;
54+
55+
pub mod library {
56+
pub use library::*;
57+
pub use parser::EMPTY_CTYPE;
58+
}
59+
}

src/parser.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::io::Read;
12
use std::mem::replace;
23
use std::path::{Path, PathBuf};
34
use std::str::FromStr;
@@ -6,7 +7,7 @@ use library::*;
67
use version::Version;
78
use xmlparser::{Element, XmlParser};
89

9-
const EMPTY_CTYPE: &str = "/*EMPTY*/";
10+
pub const EMPTY_CTYPE: &str = "/*EMPTY*/";
1011

1112
pub fn is_empty_c_type(c_type: &str) -> bool {
1213
c_type == EMPTY_CTYPE
@@ -23,6 +24,16 @@ impl Library {
2324
})
2425
}
2526

27+
pub fn read_reader<R: Read>(&mut self, reader: R) -> Result<(), String> {
28+
let dir = Path::new("read_reader_not_implement_include");
29+
let mut p = XmlParser::new(reader)?;
30+
p.document(|p, _| {
31+
p.element_with_name("repository", |parser, _elem| {
32+
self.read_repository(dir, parser)
33+
})
34+
})
35+
}
36+
2637
fn read_repository(&mut self, dir: &Path, parser: &mut XmlParser) -> Result<(), String> {
2738
let mut package = None;
2839
let mut includes = Vec::new();
@@ -48,8 +59,12 @@ impl Library {
4859
}
4960
Ok(())
5061
}
51-
"namespace" => self.read_namespace(parser, elem, package.take(),
52-
replace(&mut includes, Vec::new())),
62+
"namespace" => self.read_namespace(
63+
parser,
64+
elem,
65+
package.take(),
66+
replace(&mut includes, Vec::new()),
67+
),
5368
_ => Err(parser.unexpected_element(elem)),
5469
})?;
5570
Ok(())

src/xmlparser.rs

-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ impl<'a> XmlParser<'a> {
145145
}
146146
}
147147

148-
#[cfg(test)]
149148
pub fn new<'r, R: 'r + Read>(read: R) -> Result<XmlParser<'r>, String> {
150149
Ok(XmlParser {
151150
parser: EventReader::new(Box::new(read)),

tests/read_library.rs

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
//! This test module contains tests that use files read_library\*.gir for checking library load
2+
3+
extern crate libgir as gir;
4+
5+
mod test_util;
6+
7+
use std::fs::File;
8+
use std::io::{self, Read};
9+
use std::path::Path;
10+
11+
use gir::tests_export::*;
12+
use test_util::*;
13+
14+
fn read_library<P: AsRef<Path>>(filename: P) -> Result<(library::Library), io::Error> {
15+
let full_name = Path::new("tests")
16+
.join("read_library")
17+
.join(filename.as_ref());
18+
let cfg = create_default_config();
19+
let mut library = library::Library::new(&cfg.library_name);
20+
let (f, _) = read_parameterized(full_name)?;
21+
library.read_reader(f).unwrap();
22+
Ok(library)
23+
}
24+
25+
#[test]
26+
fn load_normal() {
27+
let cfg = create_default_config();
28+
let mut library = library::Library::new(&cfg.library_name);
29+
30+
let f = File::open("tests/read_library/normal.gir").unwrap();
31+
library.read_reader(f).unwrap();
32+
assert!(library.find_type(1, "TimeSpan").is_some());
33+
}
34+
35+
#[test]
36+
fn read_mode_default() {
37+
let (mut f, _) = read_parameterized("tests/read_library/normal.gir").unwrap();
38+
let mut buffer = vec![0u8; 6];
39+
assert_eq!(f.read(&mut buffer).unwrap(), 6);
40+
let str = String::from_utf8_lossy(&buffer);
41+
assert_eq!(str, "<?xml ");
42+
}
43+
44+
#[test]
45+
fn read_mode_full() {
46+
let (mut f, _) = read_parameterized("tests/read_library/mode_full.gir").unwrap();
47+
let mut buffer = vec![0u8; 6];
48+
assert_eq!(f.read(&mut buffer).unwrap(), 6);
49+
let str = String::from_utf8_lossy(&buffer);
50+
assert_eq!(str, "<?xml ");
51+
}
52+
53+
#[test]
54+
fn read_mode_object() {
55+
let (mut f, _) = read_parameterized("tests/read_library/mode_object.gir").unwrap();
56+
let mut buffer = vec![0u8; 6];
57+
assert_eq!(f.read(&mut buffer).unwrap(), 6);
58+
let str = String::from_utf8_lossy(&buffer);
59+
assert_eq!(str, "<?xml ");
60+
}
61+
62+
#[test]
63+
fn load_alias() {
64+
let library = read_library("alias.gir").unwrap();
65+
let a: &library::Alias = get_type(&library, "TimeSpan");
66+
assert_eq!(a.c_identifier, "TTimeSpan");
67+
assert_eq!(a.target_c_type, "gint64");
68+
assert_eq!(a.typ.full_name(&library), "*.Int64");
69+
}
70+
71+
#[test]
72+
fn load_bitfield() {
73+
let library = read_library("bitfield.gir").unwrap();
74+
let b: &library::Bitfield = get_type(&library, "AsciiType");
75+
assert_eq!(b.c_type, "TAsciiType");
76+
let m = &b.members[0];
77+
assert_eq!(m.name, "alnum");
78+
assert_eq!(m.c_identifier, "T_ASCII_ALNUM");
79+
assert_eq!(m.value, "1");
80+
let m = &b.members[1];
81+
assert_eq!(m.name, "alpha");
82+
assert_eq!(m.c_identifier, "T_ASCII_ALPHA");
83+
assert_eq!(m.value, "2");
84+
}
85+
86+
#[test]
87+
fn load_class() {
88+
let library = read_library("class.gir").unwrap();
89+
let typ_object = library.find_type(0, "GObject.Object").unwrap();
90+
let typ_app_info = library.find_type(0, "Tst.AppInfo").unwrap();
91+
let typ_variant = library.find_type(0, "GLib.Variant").unwrap();
92+
let c: &library::Class = get_type(&library, "AppLaunchContext");
93+
assert_eq!(c.c_type, "GAppLaunchContext");
94+
assert_eq!(c.type_struct, Some("AppLaunchContextClass".into()));
95+
assert_eq!(c.glib_get_type, "g_app_launch_context_get_type");
96+
assert_eq!(c.parent, Some(typ_object));
97+
assert_eq!(c.version, None);
98+
let f = &c.functions[0];
99+
assert_eq!(f.name, "new");
100+
assert_eq!(f.c_identifier, Some("g_app_launch_context_new".into()));
101+
assert_eq!(f.kind, library::FunctionKind::Constructor);
102+
assert_eq!(f.throws, false);
103+
assert_eq!(f.version, None);
104+
let f = &c.functions[1];
105+
assert_eq!(f.name, "get_environment");
106+
assert_eq!(
107+
f.c_identifier,
108+
Some("g_app_launch_context_get_environment".into())
109+
);
110+
assert_eq!(f.kind, library::FunctionKind::Method);
111+
assert_eq!(f.throws, false);
112+
assert_eq!(f.version, Some(Version::Full(2, 32, 0)));
113+
let f = &c.fields[0];
114+
assert_eq!(f.name, "parent_instance");
115+
assert_eq!(f.c_type, Some("GObject".into()));
116+
assert_eq!(f.typ, typ_object);
117+
assert_eq!(f.private, false);
118+
let s = &c.signals[0];
119+
assert_eq!(s.name, "launched");
120+
assert_eq!(s.is_action, false);
121+
assert_eq!(s.version, Some(Version::Full(2, 36, 0)));
122+
let p = &s.parameters[0];
123+
assert_eq!(p.name, "info");
124+
assert_eq!(p.c_type, library::EMPTY_CTYPE);
125+
assert_eq!(p.typ, typ_app_info);
126+
assert_eq!(p.transfer, library::Transfer::None);
127+
let p = &s.parameters[1];
128+
assert_eq!(p.name, "platform_data");
129+
assert_eq!(p.c_type, library::EMPTY_CTYPE);
130+
assert_eq!(p.typ, typ_variant);
131+
assert_eq!(p.transfer, library::Transfer::None);
132+
let p = &s.ret;
133+
assert_eq!(p.name, "");
134+
assert_eq!(p.c_type, "void");
135+
assert_eq!(p.typ.full_name(&library), "*.None");
136+
assert_eq!(p.transfer, library::Transfer::None);
137+
}
138+
139+
#[test]
140+
fn load_constant() {
141+
let library = read_library("constant.gir").unwrap();
142+
let ns = library.namespace(library::MAIN_NAMESPACE);
143+
let c = &ns.constants[0];
144+
assert_eq!(c.name, "ANALYZER_ANALYZING");
145+
assert_eq!(c.c_identifier, "T_ANALYZER_ANALYZING");
146+
assert_eq!(c.c_type, "gint");
147+
assert_eq!(c.typ.full_name(&library), "*.Int");
148+
assert_eq!(c.value, "1");
149+
}
150+
151+
#[test]
152+
fn load_enumeration() {
153+
let library = read_library("enumeration.gir").unwrap();
154+
let e: &library::Enumeration = get_type(&library, "BookmarkFileError");
155+
assert_eq!(e.c_type, "TBookmarkFileError");
156+
assert_eq!(e.error_domain, Some("t-bookmark-file-error-quark".into()));
157+
let m = &e.members[0];
158+
assert_eq!(m.name, "invalid_uri");
159+
assert_eq!(m.c_identifier, "T_BOOKMARK_FILE_ERROR_INVALID_URI");
160+
assert_eq!(m.value, "0");
161+
let m = &e.members[1];
162+
assert_eq!(m.name, "invalid_value");
163+
assert_eq!(m.c_identifier, "T_BOOKMARK_FILE_ERROR_INVALID_VALUE");
164+
assert_eq!(m.value, "1");
165+
}
166+
167+
#[test]
168+
fn load_function() {
169+
let library = read_library("function.gir").unwrap();
170+
let ns = library.namespace(library::MAIN_NAMESPACE);
171+
let f = &ns.functions[0];
172+
assert_eq!(f.name, "access");
173+
assert_eq!(f.c_identifier, Some("t_access".into()));
174+
assert_eq!(f.kind, library::FunctionKind::Global);
175+
assert_eq!(f.throws, false);
176+
assert_eq!(f.version, Some(Version::Full(2, 8, 0)));
177+
let p = &f.parameters[0];
178+
assert_eq!(p.name, "filename");
179+
assert_eq!(p.c_type, "const gchar*");
180+
assert_eq!(p.typ.full_name(&library), "*.Filename");
181+
assert_eq!(p.transfer, library::Transfer::Full);
182+
let p = &f.parameters[1];
183+
assert_eq!(p.name, "mode");
184+
assert_eq!(p.c_type, "int");
185+
assert_eq!(p.typ.full_name(&library), "*.Int");
186+
assert_eq!(p.transfer, library::Transfer::None);
187+
let p = &f.ret;
188+
assert_eq!(p.name, "");
189+
assert_eq!(p.c_type, "int");
190+
assert_eq!(p.typ.full_name(&library), "*.Int");
191+
assert_eq!(p.transfer, library::Transfer::None);
192+
}
193+
194+
//TODO: interface, record, union, callback

tests/read_library/alias.gir

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<!--mode:object-->
2+
<alias name="TimeSpan" c:type="TTimeSpan">
3+
<type name="gint64" c:type="gint64"/>
4+
</alias>

tests/read_library/bitfield.gir

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<!--mode:object-->
2+
<bitfield name="AsciiType" c:type="TAsciiType">
3+
<member name="alnum" value="1" c:identifier="T_ASCII_ALNUM">
4+
</member>
5+
<member name="alpha" value="2" c:identifier="T_ASCII_ALPHA">
6+
</member>
7+
</bitfield>

tests/read_library/class.gir

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<!--mode:object-->
2+
<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">
3+
<constructor name="new" c:identifier="g_app_launch_context_new">
4+
<return-value transfer-ownership="full">
5+
<type name="AppLaunchContext" c:type="GAppLaunchContext*"/>
6+
</return-value>
7+
</constructor>
8+
<virtual-method name="get_display" invoker="get_display">
9+
<return-value transfer-ownership="full">
10+
<type name="utf8" c:type="char*"/>
11+
</return-value>
12+
<parameters>
13+
<instance-parameter name="context" transfer-ownership="none">
14+
<type name="AppLaunchContext" c:type="GAppLaunchContext*"/>
15+
</instance-parameter>
16+
<parameter name="info" transfer-ownership="none">
17+
<type name="AppInfo" c:type="GAppInfo*"/>
18+
</parameter>
19+
<parameter name="files" transfer-ownership="none">
20+
<type name="GLib.List" c:type="GList*">
21+
<type name="File"/>
22+
</type>
23+
</parameter>
24+
</parameters>
25+
</virtual-method>
26+
<method name="get_environment" c:identifier="g_app_launch_context_get_environment" version="2.32">
27+
<return-value transfer-ownership="full">
28+
<array c:type="char**">
29+
<type name="filename"/>
30+
</array>
31+
</return-value>
32+
<parameters>
33+
<instance-parameter name="context" transfer-ownership="none">
34+
<type name="AppLaunchContext" c:type="GAppLaunchContext*"/>
35+
</instance-parameter>
36+
</parameters>
37+
</method>
38+
<field name="parent_instance">
39+
<type name="GObject.Object" c:type="GObject"/>
40+
</field>
41+
<glib:signal name="launched" when="last" version="2.36">
42+
<return-value transfer-ownership="none">
43+
<type name="none" c:type="void"/>
44+
</return-value>
45+
<parameters>
46+
<parameter name="info" transfer-ownership="none">
47+
<type name="AppInfo"/>
48+
</parameter>
49+
<parameter name="platform_data" transfer-ownership="none">
50+
<type name="GLib.Variant"/>
51+
</parameter>
52+
</parameters>
53+
</glib:signal>
54+
</class>

tests/read_library/constant.gir

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<!--mode:object-->
2+
<constant name="ANALYZER_ANALYZING" value="1" c:type="T_ANALYZER_ANALYZING">
3+
<type name="gint" c:type="gint"/>
4+
</constant>

tests/read_library/enumeration.gir

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!--mode:object-->
2+
<enumeration name="BookmarkFileError" c:type="TBookmarkFileError" glib:error-domain="t-bookmark-file-error-quark">
3+
<doc xml:space="preserve">Error codes returned by bookmark file parsing.</doc>
4+
<member name="invalid_uri" value="0" c:identifier="T_BOOKMARK_FILE_ERROR_INVALID_URI">
5+
</member>
6+
<member name="invalid_value" value="1" c:identifier="T_BOOKMARK_FILE_ERROR_INVALID_VALUE">
7+
</member>
8+
</enumeration>

tests/read_library/function.gir

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!--mode:object-->
2+
<function name="access" c:identifier="t_access" version="2.8">
3+
<return-value transfer-ownership="none">
4+
<type name="gint" c:type="int"/>
5+
</return-value>
6+
<parameters>
7+
<parameter name="filename" transfer-ownership="full">
8+
<type name="filename" c:type="const gchar*"/>
9+
</parameter>
10+
<parameter name="mode" transfer-ownership="none">
11+
<type name="gint" c:type="int"/>
12+
</parameter>
13+
</parameters>
14+
</function>

tests/read_library/mode_full.gir

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!--mode:full-->
2+
<?xml version="1.0"?>
3+
<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">
4+
<package name="tst-1.0"/>
5+
<namespace name="Tst" version="1.0" c:identifier-prefixes="T" c:symbol-prefixes="t,tst">
6+
<alias name="TimeSpan" c:type="TTimeSpan">
7+
<type name="gint64" c:type="gint64"/>
8+
</alias>
9+
</namespace>
10+
</repository>

tests/read_library/mode_object.gir

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<!--mode:object-->
2+
<alias name="TimeSpan" c:type="TTimeSpan">
3+
<type name="gint64" c:type="gint64"/>
4+
</alias>

tests/read_library/normal.gir

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0"?>
2+
<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">
3+
<package name="tst-1.0"/>
4+
<namespace name="Tst" version="1.0" c:identifier-prefixes="T" c:symbol-prefixes="t,tst">
5+
<alias name="TimeSpan" c:type="TTimeSpan">
6+
<type name="gint64" c:type="gint64"/>
7+
</alias>
8+
</namespace>
9+
</repository>

0 commit comments

Comments
 (0)