use super::specification;
use super::super::generate;
use std::io::Cursor;
#[test]
fn typedef_void() {
let s = specification(
r#"
typedef void; /* syntactically defined, semantically meaningless */
"#,
);
println!("spec {:?}", s);
assert!(s.is_err())
}
#[test]
fn kwishnames() {
let kws = vec![
"bool",
"case",
"const",
"default",
"double",
"enum",
"float",
"hyper",
"int",
"opaque",
"quadruple",
"string",
"struct",
"switch",
"typedef",
"union",
"unsigned",
"void",
];
let specs = vec![
"const {}x = 1;",
"struct {}x { int i; };",
"struct foo { int {}x; };",
"typedef int {}x;",
"union {}x switch (int x) { case 1: void; };",
"union x switch (int {}x) { case 1: void; };",
"union x switch (int y) { case 1: int {}x; };",
];
for sp in &specs {
for kw in &kws {
let spec = sp.replace("{}", kw);
let s = specification(&spec);
println!("spec {} => {:?}", spec, s);
assert!(s.is_ok())
}
}
}
#[test]
fn kwnames() {
let kws = vec![
"bool",
"case",
"const",
"default",
"double",
"enum",
"float",
"hyper",
"int",
"opaque",
"quadruple",
"string",
"struct",
"switch",
"typedef",
"union",
"unsigned",
"void",
];
let specs = vec![
"const {} = 1;",
"struct {} { int i; };",
"struct foo { int {}; };",
"typedef int {};",
"union {} switch (int x) { case 1: void; };",
"union x switch (int {}) { case 1: void; };",
"union x switch (int y) { case 1: int {}; };",
];
for sp in &specs {
for kw in &kws {
let spec = sp.replace("{}", kw);
let s = specification(&spec);
println!("spec {} => {:?}", spec, s);
assert!(s.is_err())
}
}
}
#[test]
fn inline_struct() {
let spec = r#"
struct thing {
struct { int a; int b; } thing;
};
"#;
let s = specification(spec);
println!("spec {:?}", s);
assert!(s.is_ok());
let g = generate("", Cursor::new(spec.as_bytes()), Vec::new());
assert!(g.is_err());
}
#[test]
fn inline_union() {
let spec = r#"
struct thing {
union switch(int x) { case 0: int a; case 1: int b; } thing;
};
"#;
let s = specification(spec);
println!("spec {:?}", s);
assert!(s.is_ok());
let g = generate("", Cursor::new(spec.as_bytes()), Vec::new());
assert!(g.is_err());
}
#[test]
fn case_type() {
let specs = vec![
"enum Foo { A, B, C }; union Bar switch (Foo x) { case A: void; case B: void; case C: void; };",
"union Bar switch (int x) { case 1: void; case 2: void; case 3: void; };",
];
for sp in specs {
let s = specification(sp);
println!("spec sp \"{}\" => {:?}", sp, s);
assert!(s.is_ok());
let g = generate("", Cursor::new(sp.as_bytes()), Vec::new());
assert!(g.is_ok());
}
}
#[test]
fn case_type_mismatch() {
let specs = vec![
"enum Foo { A, B, C}; union Bar switch (Foo x) { case 1: void; case 2: void; case 3: void; };",
"enum Foo { A, B, C}; union Bar switch (int x) { case A: void; case B: void; case C: void; };",
];
for sp in specs {
let s = specification(sp);
println!("spec sp \"{}\" => {:?}", sp, s);
assert!(s.is_ok());
let g = generate("", Cursor::new(sp.as_bytes()), Vec::new());
assert!(g.is_err());
}
}
#[test]
fn constants() {
let specs = vec![
"const A = 0;",
"const A = 0x0;",
"const A = 00;",
"const A = -0;",
"const A = 0x123;",
"const A = 0123;",
"const A = -0123;",
"const A = 123;",
"const A = -123;",
];
for sp in specs {
let s = specification(sp);
println!("spec sp \"{}\" => {:?}", sp, s);
assert!(s.is_ok());
let g = generate("", Cursor::new(sp.as_bytes()), Vec::new());
assert!(g.is_ok());
}
}
#[test]
fn union_simple() {
let s = specification(
r#"
union foo switch (int x) {
case 0:
int val;
};
"#,
);
println!("spec {:?}", s);
assert!(s.is_ok())
}
#[test]
fn union_default() {
let s = specification(
r#"
union foo switch (int x) {
case 0:
int val;
default:
void;
};
"#,
);
println!("spec {:?}", s);
assert!(s.is_ok())
}
#[test]
fn union_default_nonempty() {
let s = specification(
r#"
union foo switch (int x) {
case 0:
int val;
default:
bool bye;
};
"#,
);
println!("spec {:?}", s);
assert!(s.is_ok())
}
#[test]
fn fallthrough_case() {
let s = specification(
r#"
union foo switch (int x) {
case 0:
case 1:
int val;
case 2:
void;
};
"#,
);
println!("spec {:?}", s);
assert!(s.is_ok())
}