Use cargo test instead of test.py.
This makes cargo test test all the stuff in tests/rust, and thus makes tests.py unnecessary. Co-authored-by: Axel Nennker <axel.nennker@telekom.de>
This commit is contained in:
parent
87007649c8
commit
2bb3e9ba66
@ -16,5 +16,4 @@ script:
|
||||
- export CXX=g++-7
|
||||
- cargo fmt --all -- --check
|
||||
- cargo build --verbose
|
||||
- cargo test --verbose
|
||||
- python test.py -v
|
||||
- CBINDGEN_TEST_VERIFY=1 cargo test --verbose
|
||||
|
58
build.rs
Normal file
58
build.rs
Normal file
@ -0,0 +1,58 @@
|
||||
fn generate_tests() {
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
let profile = env::var("PROFILE").unwrap();
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
let mut dst = File::create(Path::new(&out_dir).join("tests.rs")).unwrap();
|
||||
|
||||
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
let tests_dir = manifest_dir.join("tests").join("rust");
|
||||
let tests = fs::read_dir(&tests_dir).unwrap();
|
||||
|
||||
let entries = tests.map(|t| t.expect("Couldn't read test file"));
|
||||
|
||||
println!("cargo:rerun-if-changed={}", tests_dir.display());
|
||||
|
||||
for entry in entries {
|
||||
let path_segment = if entry.file_type().unwrap().is_file() {
|
||||
match entry.path().extension().and_then(OsStr::to_str) {
|
||||
Some("rs") => {}
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
entry
|
||||
.path()
|
||||
.file_stem()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_owned()
|
||||
} else {
|
||||
entry.file_name().to_str().unwrap().to_owned()
|
||||
};
|
||||
|
||||
let identifier = path_segment
|
||||
.replace(|c| !char::is_alphanumeric(c), "_")
|
||||
.replace("__", "_");
|
||||
|
||||
writeln!(
|
||||
dst,
|
||||
"test_file!({}, test_{}, {:?}, {:?});",
|
||||
profile,
|
||||
identifier,
|
||||
path_segment,
|
||||
entry.path(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
dst.flush().unwrap();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
generate_tests();
|
||||
}
|
@ -23,7 +23,7 @@ pub use bindgen::rename::RenameRule;
|
||||
pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
/// A language type to generate bindings for.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum Language {
|
||||
Cxx,
|
||||
C,
|
||||
@ -129,7 +129,7 @@ impl FromStr for DocumentationStyle {
|
||||
deserialize_enum_str!(DocumentationStyle);
|
||||
|
||||
/// A style of Style to use when generating structs and enums.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum Style {
|
||||
Both,
|
||||
Tag,
|
||||
|
133
test.py
133
test.py
@ -1,133 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import glob
|
||||
import subprocess
|
||||
import sys
|
||||
import filecmp
|
||||
|
||||
def build_cbindgen():
|
||||
try:
|
||||
subprocess.check_output(["cargo", "build"])
|
||||
return True
|
||||
except subprocess.CalledProcessError:
|
||||
return False
|
||||
|
||||
def cbindgen(path, out, c, style, verify):
|
||||
bin = ["target/debug/cbindgen"]
|
||||
compile = [path, "-o", out]
|
||||
flags = []
|
||||
|
||||
if c:
|
||||
flags += ["--lang", "c"]
|
||||
|
||||
if style:
|
||||
flags += ["--style", style]
|
||||
|
||||
if verify:
|
||||
flags += ["--verify"]
|
||||
|
||||
config = path.replace(".rs", ".toml")
|
||||
if not os.path.isdir(path) and os.path.exists(config):
|
||||
flags += ["--config", config]
|
||||
|
||||
command = bin + flags + compile
|
||||
print(command)
|
||||
subprocess.check_output(bin + flags + compile)
|
||||
|
||||
def gcc(src):
|
||||
gcc_bin = os.environ.get('CC')
|
||||
if gcc_bin == None:
|
||||
gcc_bin = 'gcc'
|
||||
|
||||
subprocess.check_output([gcc_bin, "-D", "DEFINED", "-c", src, "-o", "tests/expectations/tmp.o"])
|
||||
os.remove("tests/expectations/tmp.o")
|
||||
|
||||
def gxx(src):
|
||||
gxx_bin = os.environ.get('CXX')
|
||||
if gxx_bin == None:
|
||||
gxx_bin = 'g++'
|
||||
|
||||
subprocess.check_output([gxx_bin, "-D", "DEFINED", "-std=c++17", "-c", src, "-o", "tests/expectations/tmp.o"])
|
||||
os.remove("tests/expectations/tmp.o")
|
||||
|
||||
def run_compile_test(rust_src, verify, c, style=""):
|
||||
is_crate = os.path.isdir(rust_src)
|
||||
|
||||
test_name = rust_src
|
||||
if is_crate:
|
||||
test_name = os.path.basename(rust_src[0:-1])
|
||||
else:
|
||||
test_name = os.path.splitext(os.path.basename(rust_src))[0]
|
||||
|
||||
expectation = True
|
||||
if test_name.startswith("fail-"):
|
||||
expectation = False
|
||||
|
||||
if c:
|
||||
subdir = style if style != "type" else ""
|
||||
out = os.path.join('tests/expectations/', subdir, test_name + ".c")
|
||||
else:
|
||||
out = os.path.join('tests/expectations/', test_name + ".cpp")
|
||||
|
||||
try:
|
||||
cbindgen(rust_src, out, c, style, verify)
|
||||
except subprocess.CalledProcessError:
|
||||
return False;
|
||||
|
||||
try:
|
||||
if c:
|
||||
gcc(out)
|
||||
else:
|
||||
gxx(out)
|
||||
except subprocess.CalledProcessError:
|
||||
return expectation == False
|
||||
|
||||
return expectation == True
|
||||
|
||||
if not build_cbindgen():
|
||||
exit()
|
||||
|
||||
args = sys.argv[1:]
|
||||
files = [x for x in args if not x.startswith("-")]
|
||||
flags = [x for x in args if x.startswith("-")]
|
||||
|
||||
verify = False
|
||||
|
||||
for flag in flags:
|
||||
if flag == "-v":
|
||||
verify = True
|
||||
|
||||
tests = []
|
||||
if len(files) == 0:
|
||||
tests = glob.glob("tests/rust/*.rs") + glob.glob("tests/rust/*/")
|
||||
else:
|
||||
tests = files
|
||||
|
||||
num_pass = 0
|
||||
num_fail = 0
|
||||
|
||||
# C
|
||||
|
||||
for test in tests:
|
||||
for style in ["type", "tag", "both"]:
|
||||
if run_compile_test(test, verify, True, style):
|
||||
num_pass += 1
|
||||
print("Pass - %s" % test)
|
||||
else:
|
||||
num_fail += 1
|
||||
print("Fail - %s" % test)
|
||||
|
||||
# C++
|
||||
|
||||
for test in tests:
|
||||
if run_compile_test(test, verify, False):
|
||||
num_pass += 1
|
||||
print("Pass - %s" % test)
|
||||
else:
|
||||
num_fail += 1
|
||||
print("Fail - %s" % test)
|
||||
|
||||
print("Tests complete. %i passed, %i failed." % (num_pass, num_fail))
|
||||
if num_fail > 0:
|
||||
sys.exit(1)
|
@ -1,9 +0,0 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* The root of all evil.
|
||||
*/
|
||||
void root(void);
|
@ -1,9 +0,0 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* The root of all evil.
|
||||
*/
|
||||
void root(void);
|
@ -1,12 +0,0 @@
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
* The root of all evil.
|
||||
*/
|
||||
void root();
|
||||
|
||||
} // extern "C"
|
@ -1,9 +0,0 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* The root of all evil.
|
||||
*/
|
||||
void root(void);
|
135
tests/tests.rs
Normal file
135
tests/tests.rs
Normal file
@ -0,0 +1,135 @@
|
||||
extern crate cbindgen;
|
||||
|
||||
use cbindgen::*;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::{env, fs};
|
||||
|
||||
fn run_cbindgen(
|
||||
profile: &'static str,
|
||||
path: &Path,
|
||||
output: &Path,
|
||||
language: Language,
|
||||
style: Option<Style>,
|
||||
) {
|
||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
let program = Path::new(&crate_dir)
|
||||
.join("target")
|
||||
.join(profile)
|
||||
.join("cbindgen");
|
||||
|
||||
let mut command = Command::new(program);
|
||||
match language {
|
||||
Language::Cxx => {}
|
||||
Language::C => {
|
||||
command.arg("--lang").arg("c");
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(style) = style {
|
||||
command.arg("--style");
|
||||
command.arg(match style {
|
||||
Style::Both => "both",
|
||||
Style::Tag => "tag",
|
||||
Style::Type => "type",
|
||||
});
|
||||
}
|
||||
|
||||
command.arg("-o").arg(output);
|
||||
|
||||
if env::var("CBINDGEN_TEST_VERIFY").is_ok() {
|
||||
command.arg("--verify");
|
||||
}
|
||||
|
||||
let mut config = path.clone().to_path_buf();
|
||||
config.set_extension("toml");
|
||||
if config.exists() {
|
||||
command.arg("--config").arg(config);
|
||||
}
|
||||
|
||||
command.arg(path);
|
||||
|
||||
println!("Running: {:?}", command);
|
||||
let cbindgen_output = command.output().expect("failed to execute process");
|
||||
assert!(
|
||||
cbindgen_output.status.success(),
|
||||
"cbindgen failed: {:?}",
|
||||
output
|
||||
);
|
||||
}
|
||||
|
||||
fn compile(cbindgen_output: &Path, language: Language) {
|
||||
let cc = env::var("CC").unwrap_or_else(|_| match language {
|
||||
Language::Cxx => "g++".to_owned(),
|
||||
Language::C => "gcc".to_owned(),
|
||||
});
|
||||
|
||||
let mut object = cbindgen_output.to_path_buf();
|
||||
object.set_extension("o");
|
||||
|
||||
let mut command = Command::new(cc);
|
||||
command.arg("-D").arg("DEFINED");
|
||||
command.arg("-c").arg(cbindgen_output);
|
||||
command.arg("-o").arg(&object);
|
||||
|
||||
println!("Running: {:?}", command);
|
||||
let out = command.output().expect("failed to compile");
|
||||
assert!(out.status.success(), "Output failed to compile: {:?}", out);
|
||||
|
||||
if object.exists() {
|
||||
fs::remove_file(object).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn run_compile_test(
|
||||
profile: &'static str,
|
||||
name: &'static str,
|
||||
path: &Path,
|
||||
language: Language,
|
||||
style: Option<Style>,
|
||||
) {
|
||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
let mut output = Path::new(&crate_dir).join("tests").join("expectations");
|
||||
if let Some(style) = style {
|
||||
match style {
|
||||
Style::Both => {
|
||||
output.push("both");
|
||||
}
|
||||
Style::Tag => {
|
||||
output.push("tag");
|
||||
}
|
||||
Style::Type => {}
|
||||
}
|
||||
}
|
||||
match language {
|
||||
Language::Cxx => {
|
||||
output.push(format!("{}.cpp", name));
|
||||
}
|
||||
Language::C => {
|
||||
output.push(format!("{}.c", name));
|
||||
}
|
||||
}
|
||||
|
||||
run_cbindgen(profile, path, &output, language, style);
|
||||
compile(&output, language);
|
||||
}
|
||||
|
||||
fn test_file(profile: &'static str, name: &'static str, filename: &'static str) {
|
||||
let test = Path::new(filename);
|
||||
for style in &[Style::Type, Style::Tag, Style::Both] {
|
||||
run_compile_test(profile, name, &test, Language::C, Some(*style));
|
||||
}
|
||||
run_compile_test(profile, name, &test, Language::Cxx, None);
|
||||
}
|
||||
|
||||
macro_rules! test_file {
|
||||
($profile:ident, $test_function_name:ident, $name:expr, $file:tt) => {
|
||||
#[test]
|
||||
fn $test_function_name() {
|
||||
test_file(stringify!($profile), $name, $file);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// This file is generated by build.rs
|
||||
include!(concat!(env!("OUT_DIR"), "/tests.rs"));
|
Loading…
x
Reference in New Issue
Block a user