diff --git a/.travis.yml b/.travis.yml
index a2bcfe232322f386857bf6445dbe061b23cb9481..963b0e82a49a32914e6759af221350421e12d41e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,3 +6,11 @@ rust:
 matrix:
   allow_failures:
   - rust: nightly
+addons:
+    apt:
+      packages:
+        - g++
+script:
+  - cargo build --verbose
+  - cargo test --verbose
+  - python run-tests.py
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index f68a468bd45723143ebb34ea5e6c05469b2f04e1..ddf2216add155487771ce88df7922e27fd9dc9d8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,6 +1,6 @@
 [root]
 name = "cbindgen"
-version = "0.1.7"
+version = "0.1.8"
 dependencies = [
  "clap 2.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/README.md b/README.md
index 45b0e1b069c406369bafce82deeb321a3b28e0d8..d7af7c1b6cc91f6f25252629bfcb592f35865c72 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ fn main() {
 
 ## Examples
 
-See `samples/` for some examples of rust source that can be handled.
+See `tests/` for some examples of rust source that can be handled.
 
 ## How it works
 
diff --git a/run-tests.py b/run-tests.py
new file mode 100755
index 0000000000000000000000000000000000000000..12aa454ce9832ba721a893dbdfb8b07ee5a96a88
--- /dev/null
+++ b/run-tests.py
@@ -0,0 +1,46 @@
+#!/bin/python
+
+import os
+import glob
+import subprocess
+import sys
+
+def cbindgen(rust_src, out):
+    subprocess.check_output(["cargo", "run", "--", rust_src, "-o", out])
+
+def gxx(src):
+    subprocess.check_output(["g++", "-c", src, "-o", "tests/tmp.o"])
+    os.remove("tests/tmp.o")
+
+def run_compile_test(rust_src, leave_output):
+    out = rust_src.replace(".rs", ".cpp")
+    try:
+        cbindgen(rust_src, out)
+        gxx(out)
+        if not leave_output:
+            os.remove(out)
+    except subprocess.CalledProcessError:
+        if not leave_output and os.path.exists(out):
+            os.remove(out)
+        return False
+
+    return True
+
+tests = glob.glob("tests/*.rs")
+num_pass = 0
+num_fail = 0
+
+leave_output = False
+
+if len(sys.argv) == 2 and sys.argv[1] == "-l":
+    leave_output = True
+
+for test in tests:
+    if run_compile_test(test, leave_output):
+        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))
diff --git a/samples/build-script/Cargo.toml b/samples/build-script/Cargo.toml
deleted file mode 100644
index 9c470fd1e5d21a2992cd09efd49f331ad9ab545d..0000000000000000000000000000000000000000
--- a/samples/build-script/Cargo.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-[package]
-name = "build-script"
-version = "0.1.0"
-authors = ["Ryan Hunt <rhunt@eqrion.net>"]
-build = "build.rs"
-
-[build-dependencies]
-cbindgen = { path = "../../" }
diff --git a/samples/build-script/build.rs b/samples/build-script/build.rs
deleted file mode 100644
index cace819f22f8f6f86940dfdd252b8e59a5ea78a0..0000000000000000000000000000000000000000
--- a/samples/build-script/build.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-extern crate cbindgen;
-
-use std::env;
-use cbindgen::{Config, Library};
-
-fn main() {
-    let root = env::var("CARGO_MANIFEST_DIR").unwrap();
-    let config = Config::from_root_or_default(&root);
-
-    Library::load(&root, &config)
-        .generate().unwrap()
-        .write_to_file("bindings.h");
-}
diff --git a/samples/build-script/cbindgen.toml b/samples/build-script/cbindgen.toml
deleted file mode 100644
index 005d92d6c2f95b6bb0b47c59ed53df44ce17ccb5..0000000000000000000000000000000000000000
--- a/samples/build-script/cbindgen.toml
+++ /dev/null
@@ -1,18 +0,0 @@
-include_guard = "build_script_h"
-include_version = true
-braces = "NextLine"
-tab_width = 4
-language = "C++"
-
-[enum]
-rename_variants = "SnakeCase"
-
-[fn]
-rename_args = "UpperCase"
-args = "Vertical"
-
-[struct]
-rename_fields = "GeckoCase"
-derive_eq = true
-derive_lt = true
-derive_lte = true
diff --git a/samples/build-script/src/lib.rs b/samples/build-script/src/lib.rs
deleted file mode 100644
index 6947652832e30e57f0001504749e0f1d9eb3a197..0000000000000000000000000000000000000000
--- a/samples/build-script/src/lib.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-#![allow(dead_code)]
-#![allow(unused_variables)]
-
-#[repr(u32)]
-pub enum Options {
-    First,
-    Second,
-    LastOne,
-}
-
-pub struct Opaque {
-    x: i32,
-    y: f32,
-}
-
-/// cbindgen:rename-all=UpperCase
-#[repr(C)]
-pub struct Normal {
-    x: i32,
-    y: f32,
-}
-
-#[repr(C)]
-pub struct Comparable {
-    x: i32,
-}
-
-#[repr(C)]
-pub struct TupleStruct(i32, f32);
-
-#[no_mangle]
-pub extern "C" fn root(x: *mut Opaque,
-                       y: Normal,
-                       z: Comparable,
-                       w: Options,
-                       a: TupleStruct)
-{
-
-}
diff --git a/samples/directive.rs b/samples/directive.rs
deleted file mode 100644
index 7a8c41ff9173145b6b3e5e192263c5cc100d4098..0000000000000000000000000000000000000000
--- a/samples/directive.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-/// cbindgen:struct-gen-op-lt=true
-/// cbindgen:struct-gen-op-lte=true
-#[repr(C)]
-struct A(i32);
-
-/// cbindgen:field-names=[x, y]
-#[repr(C)]
-struct B(i32, f32);
-
-/// cbindgen:enum-trailing-values=[Z, W]
-#[repr(u32)]
-enum C {
-    X = 2,
-    Y,
-}
-
-/// cbindgen:function-prefix=PREFIX
-/// cbindgen:function-postfix=PREFIX
-#[no_mangle]
-extern "C" fn root(x: A, y: B, z: C) {
-}
diff --git a/samples/fn-ptr.rs b/samples/fn-ptr.rs
deleted file mode 100644
index 35b1f1849d9c9f1df5226468f3e6fcd5994e7919..0000000000000000000000000000000000000000
--- a/samples/fn-ptr.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-type Callback = fn (i32, i32) -> bool;
-
-#[no_mangle]
-extern "C" fn root(x: fn(), y: Callback)
-{
-
-}
diff --git a/samples/struct.rs b/samples/struct.rs
deleted file mode 100644
index 713bb8208f8c3d4554b4a31a12cdcfaa6e899876..0000000000000000000000000000000000000000
--- a/samples/struct.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-struct Opaque {
-    x: i32,
-    y: f32,
-}
-
-#[repr(C)]
-struct Normal {
-    x: i32,
-    y: f32,
-}
-
-#[repr(C)]
-struct Tuple(i32, f32);
-
-/// cbindgen:field-names=[x, y]
-#[repr(C)]
-struct TupleNamed(i32, f32);
-
-#[no_mangle]
-extern "C" fn root(x: *mut Opaque, y: Normal, z: Tuple, w: TupleNamed)
-{
-
-}
diff --git a/samples/alias.rs b/tests/alias.rs
similarity index 56%
rename from samples/alias.rs
rename to tests/alias.rs
index 2c453606a3d1764195ec08b4fd6157a8da46ee7a..435e70797174156e54a51a7378017d25239ccc57 100644
--- a/samples/alias.rs
+++ b/tests/alias.rs
@@ -1,21 +1,18 @@
 #[repr(C)]
-struct Dep
-{
+struct Dep {
     a: i32,
     b: f32,
 }
 
 #[repr(C)]
-struct Foo<X>
-{
+struct Foo<X> {
     a: X,
     b: X,
     c: Dep,
 }
 
 #[repr(u32)]
-enum Status
-{
+enum Status {
     Ok,
     Err,
 }
@@ -27,7 +24,8 @@ type Unit = i32;
 type SpecialStatus = Status;
 
 #[no_mangle]
-extern "C" fn root(x: IntFoo, y: DoubleFoo, z: Unit, w: SpecialStatus)
-{
-
-}
+extern "C" fn root(x: IntFoo,
+                   y: DoubleFoo,
+                   z: Unit,
+                   w: SpecialStatus)
+{ }
diff --git a/tests/directive.rs b/tests/directive.rs
new file mode 100644
index 0000000000000000000000000000000000000000..b078921a88a3122e9248fd192b05df6f71146c2a
--- /dev/null
+++ b/tests/directive.rs
@@ -0,0 +1,22 @@
+/// cbindgen:derive-lt=true
+/// cbindgen:derive-lte=true
+/// cbindgen:rename-all=GeckoCase
+#[repr(C)]
+struct A(i32);
+
+/// cbindgen:field-names=[x, y]
+#[repr(C)]
+struct B(i32, f32);
+
+/// cbindgen:trailing-values=[Z, W]
+#[repr(u32)]
+enum C {
+    X = 2,
+    Y,
+}
+
+#[no_mangle]
+extern "C" fn root(x: A,
+                   y: B,
+                   z: C)
+{ }
diff --git a/samples/enum.rs b/tests/enum.rs
similarity index 68%
rename from samples/enum.rs
rename to tests/enum.rs
index 41582398070aee60121c84a1c219a825c7802aa4..99d945c4527369a33550fad79b28078474613cbc 100644
--- a/samples/enum.rs
+++ b/tests/enum.rs
@@ -28,7 +28,8 @@ enum C {
 }
 
 #[no_mangle]
-extern "C" fn root(x: *mut Opaque, y: A, z: B, w: C)
-{
-
-}
+extern "C" fn root(x: *mut Opaque,
+                   y: A,
+                   z: B,
+                   w: C)
+{ }
diff --git a/tests/fn-ptr.rs b/tests/fn-ptr.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a0f2763d18e45483550d0710fcced8151d517df4
--- /dev/null
+++ b/tests/fn-ptr.rs
@@ -0,0 +1,6 @@
+type Callback = fn (i32, i32) -> bool;
+
+#[no_mangle]
+extern "C" fn root(x: fn(),
+                   y: Callback)
+{ }
diff --git a/tests/struct.rs b/tests/struct.rs
new file mode 100644
index 0000000000000000000000000000000000000000..428d5baea58d099e6b9a6f2daf3d545fe84b7e78
--- /dev/null
+++ b/tests/struct.rs
@@ -0,0 +1,25 @@
+struct Opaque {
+    x: i32,
+    y: f32,
+}
+
+#[repr(C)]
+struct Normal {
+    x: i32,
+    y: f32,
+}
+
+/// cbindgen:rename-all=GeckoCase
+#[repr(C)]
+struct TupleRenamed(i32, f32);
+
+/// cbindgen:field-names=[x, y]
+#[repr(C)]
+struct TupleNamed(i32, f32);
+
+#[no_mangle]
+extern "C" fn root(x: *mut Opaque,
+                   y: Normal,
+                   z: TupleRenamed,
+                   w: TupleNamed)
+{ }