Move tests to snapshot testing via insta
diff --git a/Cargo.toml b/Cargo.toml
index 7cd3fca..f13e6ab 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -40,6 +40,7 @@
 
 [dev-dependencies]
 colored = "1.7"
+insta = "0.7"
 rayon = "1.0"
 regex = "1.0"
 walkdir = "2.1"
diff --git a/tests/macros/mod.rs b/tests/macros/mod.rs
index 1b63ca1..a7f62c9 100644
--- a/tests/macros/mod.rs
+++ b/tests/macros/mod.rs
@@ -1,3 +1,8 @@
+extern crate proc_macro2;
+
+use syn;
+use syn::parse::{Parse, Result};
+
 #[macro_export]
 macro_rules! errorf {
     ($($tt:tt)*) => {{
@@ -21,3 +26,43 @@
         punctuated!($($e,)+)
     };
 }
+
+#[macro_export]
+macro_rules! snapshot {
+    ($($args:tt)*) => {
+        snapshot_impl!(() $($args)*)
+    };
+}
+
+#[macro_export]
+macro_rules! snapshot_impl {
+    (($($expr:tt)*) as $t:ty) => {{
+        let syntax_tree = ::macros::Tokens::parse::<$t>($($expr)*).unwrap();
+        insta::assert_debug_snapshot_matches!(syntax_tree);
+        syntax_tree
+    }};
+    (($($expr:tt)*)) => {{
+        let syntax_tree = $($expr)*;
+        insta::assert_debug_snapshot_matches!(syntax_tree);
+        syntax_tree
+    }};
+    (($($expr:tt)*) $next:tt $($rest:tt)*) => {
+        snapshot_impl!(($($expr)* $next) $($rest)*)
+    };
+}
+
+pub trait Tokens {
+    fn parse<T: Parse>(self) -> Result<T>;
+}
+
+impl<'a> Tokens for &'a str {
+    fn parse<T: Parse>(self) -> Result<T> {
+        syn::parse_str(self)
+    }
+}
+
+impl Tokens for proc_macro2::TokenStream {
+    fn parse<T: Parse>(self) -> Result<T> {
+        syn::parse2(self)
+    }
+}
diff --git a/tests/snapshots/test_asyncness__async_closure.snap b/tests/snapshots/test_asyncness__async_closure.snap
new file mode 100644
index 0000000..694d812
--- /dev/null
+++ b/tests/snapshots/test_asyncness__async_closure.snap
@@ -0,0 +1,30 @@
+---
+created: "2019-03-11T05:39:50.464048036Z"
+creator: insta@0.7.1
+source: tests/test_asyncness.rs
+expression: syntax_tree
+---
+Closure(
+    ExprClosure {
+        attrs: [],
+        asyncness: Some(
+            Async
+        ),
+        movability: None,
+        capture: None,
+        or1_token: Or,
+        inputs: [],
+        or2_token: Or,
+        output: Default,
+        body: Block(
+            ExprBlock {
+                attrs: [],
+                label: None,
+                block: Block {
+                    brace_token: Brace,
+                    stmts: []
+                }
+            }
+        )
+    }
+)
diff --git a/tests/snapshots/test_asyncness__async_fn.snap b/tests/snapshots/test_asyncness__async_fn.snap
new file mode 100644
index 0000000..4328934
--- /dev/null
+++ b/tests/snapshots/test_asyncness__async_fn.snap
@@ -0,0 +1,38 @@
+---
+created: "2019-03-11T05:39:50.464009531Z"
+creator: insta@0.7.1
+source: tests/test_asyncness.rs
+expression: syntax_tree
+---
+Fn(
+    ItemFn {
+        attrs: [],
+        vis: Inherited,
+        constness: None,
+        unsafety: None,
+        asyncness: Some(
+            Async
+        ),
+        abi: None,
+        ident: Ident(
+            process
+        ),
+        decl: FnDecl {
+            fn_token: Fn,
+            generics: Generics {
+                lt_token: None,
+                params: [],
+                gt_token: None,
+                where_clause: None
+            },
+            paren_token: Paren,
+            inputs: [],
+            variadic: None,
+            output: Default
+        },
+        block: Block {
+            brace_token: Brace,
+            stmts: []
+        }
+    }
+)
diff --git a/tests/snapshots/test_attribute__bool_lit-2.snap b/tests/snapshots/test_attribute__bool_lit-2.snap
new file mode 100644
index 0000000..e28d068
--- /dev/null
+++ b/tests/snapshots/test_attribute__bool_lit-2.snap
@@ -0,0 +1,24 @@
+---
+created: "2019-03-11T05:39:58.894785578Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Literal(
+                Bool(
+                    LitBool {
+                        value: true,
+                        span: Span
+                    }
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_attribute__bool_lit.snap b/tests/snapshots/test_attribute__bool_lit.snap
new file mode 100644
index 0000000..dcaa567
--- /dev/null
+++ b/tests/snapshots/test_attribute__bool_lit.snap
@@ -0,0 +1,24 @@
+---
+created: "2019-03-11T05:39:56.764147500Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Literal(
+                Bool(
+                    LitBool {
+                        value: true,
+                        span: Span
+                    }
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_bool_value-2.snap b/tests/snapshots/test_attribute__meta_item_bool_value-2.snap
new file mode 100644
index 0000000..bde8a7b
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_bool_value-2.snap
@@ -0,0 +1,20 @@
+---
+created: "2019-03-11T05:39:58.894781289Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+NameValue(
+    MetaNameValue {
+        ident: Ident(
+            foo
+        ),
+        eq_token: Eq,
+        lit: Bool(
+            LitBool {
+                value: true,
+                span: Span
+            }
+        )
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_bool_value-3.snap b/tests/snapshots/test_attribute__meta_item_bool_value-3.snap
new file mode 100644
index 0000000..757679f
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_bool_value-3.snap
@@ -0,0 +1,20 @@
+---
+created: "2019-03-11T05:40:00.962390546Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+NameValue(
+    MetaNameValue {
+        ident: Ident(
+            foo
+        ),
+        eq_token: Eq,
+        lit: Bool(
+            LitBool {
+                value: false,
+                span: Span
+            }
+        )
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_bool_value-4.snap b/tests/snapshots/test_attribute__meta_item_bool_value-4.snap
new file mode 100644
index 0000000..1fae71b
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_bool_value-4.snap
@@ -0,0 +1,20 @@
+---
+created: "2019-03-11T05:40:02.824077655Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+NameValue(
+    MetaNameValue {
+        ident: Ident(
+            foo
+        ),
+        eq_token: Eq,
+        lit: Bool(
+            LitBool {
+                value: false,
+                span: Span
+            }
+        )
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_bool_value.snap b/tests/snapshots/test_attribute__meta_item_bool_value.snap
new file mode 100644
index 0000000..35b1a62
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_bool_value.snap
@@ -0,0 +1,20 @@
+---
+created: "2019-03-11T05:39:56.764147498Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+NameValue(
+    MetaNameValue {
+        ident: Ident(
+            foo
+        ),
+        eq_token: Eq,
+        lit: Bool(
+            LitBool {
+                value: true,
+                span: Span
+            }
+        )
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_list_bool_value-2.snap b/tests/snapshots/test_attribute__meta_item_list_bool_value-2.snap
new file mode 100644
index 0000000..33a0f78
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_list_bool_value-2.snap
@@ -0,0 +1,32 @@
+---
+created: "2019-03-11T05:39:58.894795070Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Meta(
+                NameValue(
+                    MetaNameValue {
+                        ident: Ident(
+                            bar
+                        ),
+                        eq_token: Eq,
+                        lit: Bool(
+                            LitBool {
+                                value: true,
+                                span: Span
+                            }
+                        )
+                    }
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_list_bool_value.snap b/tests/snapshots/test_attribute__meta_item_list_bool_value.snap
new file mode 100644
index 0000000..3bd25d5
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_list_bool_value.snap
@@ -0,0 +1,32 @@
+---
+created: "2019-03-11T05:39:56.764179861Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Meta(
+                NameValue(
+                    MetaNameValue {
+                        ident: Ident(
+                            bar
+                        ),
+                        eq_token: Eq,
+                        lit: Bool(
+                            LitBool {
+                                value: true,
+                                span: Span
+                            }
+                        )
+                    }
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_list_lit-2.snap b/tests/snapshots/test_attribute__meta_item_list_lit-2.snap
new file mode 100644
index 0000000..9e2ad09
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_list_lit-2.snap
@@ -0,0 +1,25 @@
+---
+created: "2019-03-11T05:39:58.894786310Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Literal(
+                Int(
+                    LitInt {
+                        token: Literal {
+                            lit: 5
+                        }
+                    }
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_list_lit.snap b/tests/snapshots/test_attribute__meta_item_list_lit.snap
new file mode 100644
index 0000000..34bfcc1
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_list_lit.snap
@@ -0,0 +1,25 @@
+---
+created: "2019-03-11T05:39:56.764180712Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Literal(
+                Int(
+                    LitInt {
+                        token: Literal {
+                            lit: 5
+                        }
+                    }
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_list_name_value-2.snap b/tests/snapshots/test_attribute__meta_item_list_name_value-2.snap
new file mode 100644
index 0000000..00e56df
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_list_name_value-2.snap
@@ -0,0 +1,33 @@
+---
+created: "2019-03-11T05:39:58.909429817Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Meta(
+                NameValue(
+                    MetaNameValue {
+                        ident: Ident(
+                            bar
+                        ),
+                        eq_token: Eq,
+                        lit: Int(
+                            LitInt {
+                                token: Literal {
+                                    lit: 5
+                                }
+                            }
+                        )
+                    }
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_list_name_value.snap b/tests/snapshots/test_attribute__meta_item_list_name_value.snap
new file mode 100644
index 0000000..83447c3
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_list_name_value.snap
@@ -0,0 +1,33 @@
+---
+created: "2019-03-11T05:39:56.775177870Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Meta(
+                NameValue(
+                    MetaNameValue {
+                        ident: Ident(
+                            bar
+                        ),
+                        eq_token: Eq,
+                        lit: Int(
+                            LitInt {
+                                token: Literal {
+                                    lit: 5
+                                }
+                            }
+                        )
+                    }
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_list_word-2.snap b/tests/snapshots/test_attribute__meta_item_list_word-2.snap
new file mode 100644
index 0000000..db11a05
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_list_word-2.snap
@@ -0,0 +1,23 @@
+---
+created: "2019-03-11T05:39:58.909418119Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Meta(
+                Word(
+                    Ident(
+                        bar
+                    )
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_list_word.snap b/tests/snapshots/test_attribute__meta_item_list_word.snap
new file mode 100644
index 0000000..da3b4fe
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_list_word.snap
@@ -0,0 +1,23 @@
+---
+created: "2019-03-11T05:39:56.777566785Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Meta(
+                Word(
+                    Ident(
+                        bar
+                    )
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_multiple-2.snap b/tests/snapshots/test_attribute__meta_item_multiple-2.snap
new file mode 100644
index 0000000..5c73260
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_multiple-2.snap
@@ -0,0 +1,79 @@
+---
+created: "2019-03-11T05:39:58.913038051Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Meta(
+                Word(
+                    Ident(
+                        word
+                    )
+                )
+            ),
+            Comma,
+            Meta(
+                NameValue(
+                    MetaNameValue {
+                        ident: Ident(
+                            name
+                        ),
+                        eq_token: Eq,
+                        lit: Int(
+                            LitInt {
+                                token: Literal {
+                                    lit: 5
+                                }
+                            }
+                        )
+                    }
+                )
+            ),
+            Comma,
+            Meta(
+                List(
+                    MetaList {
+                        ident: Ident(
+                            list
+                        ),
+                        paren_token: Paren,
+                        nested: [
+                            Meta(
+                                NameValue(
+                                    MetaNameValue {
+                                        ident: Ident(
+                                            name2
+                                        ),
+                                        eq_token: Eq,
+                                        lit: Int(
+                                            LitInt {
+                                                token: Literal {
+                                                    lit: 6
+                                                }
+                                            }
+                                        )
+                                    }
+                                )
+                            )
+                        ]
+                    }
+                )
+            ),
+            Comma,
+            Meta(
+                Word(
+                    Ident(
+                        word2
+                    )
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_multiple.snap b/tests/snapshots/test_attribute__meta_item_multiple.snap
new file mode 100644
index 0000000..88adea1
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_multiple.snap
@@ -0,0 +1,79 @@
+---
+created: "2019-03-11T05:39:56.781580510Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Meta(
+                Word(
+                    Ident(
+                        word
+                    )
+                )
+            ),
+            Comma,
+            Meta(
+                NameValue(
+                    MetaNameValue {
+                        ident: Ident(
+                            name
+                        ),
+                        eq_token: Eq,
+                        lit: Int(
+                            LitInt {
+                                token: Literal {
+                                    lit: 5
+                                }
+                            }
+                        )
+                    }
+                )
+            ),
+            Comma,
+            Meta(
+                List(
+                    MetaList {
+                        ident: Ident(
+                            list
+                        ),
+                        paren_token: Paren,
+                        nested: [
+                            Meta(
+                                NameValue(
+                                    MetaNameValue {
+                                        ident: Ident(
+                                            name2
+                                        ),
+                                        eq_token: Eq,
+                                        lit: Int(
+                                            LitInt {
+                                                token: Literal {
+                                                    lit: 6
+                                                }
+                                            }
+                                        )
+                                    }
+                                )
+                            )
+                        ]
+                    }
+                )
+            ),
+            Comma,
+            Meta(
+                Word(
+                    Ident(
+                        word2
+                    )
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_name_value-2.snap b/tests/snapshots/test_attribute__meta_item_name_value-2.snap
new file mode 100644
index 0000000..621ac30
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_name_value-2.snap
@@ -0,0 +1,21 @@
+---
+created: "2019-03-11T05:39:58.912645460Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+NameValue(
+    MetaNameValue {
+        ident: Ident(
+            foo
+        ),
+        eq_token: Eq,
+        lit: Int(
+            LitInt {
+                token: Literal {
+                    lit: 5
+                }
+            }
+        )
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_name_value.snap b/tests/snapshots/test_attribute__meta_item_name_value.snap
new file mode 100644
index 0000000..e3ddf52
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_name_value.snap
@@ -0,0 +1,21 @@
+---
+created: "2019-03-11T05:39:56.782341532Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+NameValue(
+    MetaNameValue {
+        ident: Ident(
+            foo
+        ),
+        eq_token: Eq,
+        lit: Int(
+            LitInt {
+                token: Literal {
+                    lit: 5
+                }
+            }
+        )
+    }
+)
diff --git a/tests/snapshots/test_attribute__meta_item_word-2.snap b/tests/snapshots/test_attribute__meta_item_word-2.snap
new file mode 100644
index 0000000..506bd55
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_word-2.snap
@@ -0,0 +1,11 @@
+---
+created: "2019-03-11T05:39:58.922674616Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+Word(
+    Ident(
+        foo
+    )
+)
diff --git a/tests/snapshots/test_attribute__meta_item_word.snap b/tests/snapshots/test_attribute__meta_item_word.snap
new file mode 100644
index 0000000..e4a0245
--- /dev/null
+++ b/tests/snapshots/test_attribute__meta_item_word.snap
@@ -0,0 +1,11 @@
+---
+created: "2019-03-11T05:39:56.788344806Z"
+creator: insta@0.7.1
+source: tests/test_attribute.rs
+expression: syntax_tree
+---
+Word(
+    Ident(
+        foo
+    )
+)
diff --git a/tests/snapshots/test_derive_input__ambiguous_crate.snap b/tests/snapshots/test_derive_input__ambiguous_crate.snap
new file mode 100644
index 0000000..a9cdc28
--- /dev/null
+++ b/tests/snapshots/test_derive_input__ambiguous_crate.snap
@@ -0,0 +1,63 @@
+---
+created: "2019-03-11T05:40:04.790707788Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [],
+    vis: Inherited,
+    ident: Ident(
+        S
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unnamed(
+                FieldsUnnamed {
+                    paren_token: Paren,
+                    unnamed: [
+                        Field {
+                            attrs: [],
+                            vis: Inherited,
+                            ident: None,
+                            colon_token: None,
+                            ty: Path(
+                                TypePath {
+                                    qself: None,
+                                    path: Path {
+                                        leading_colon: None,
+                                        segments: [
+                                            PathSegment {
+                                                ident: Ident(
+                                                    crate
+                                                ),
+                                                arguments: None
+                                            },
+                                            Colon2,
+                                            PathSegment {
+                                                ident: Ident(
+                                                    X
+                                                ),
+                                                arguments: None
+                                            }
+                                        ]
+                                    }
+                                }
+                            )
+                        }
+                    ]
+                }
+            ),
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__attr_with_mod_style_path_with_self.snap b/tests/snapshots/test_derive_input__attr_with_mod_style_path_with_self.snap
new file mode 100644
index 0000000..be01c35
--- /dev/null
+++ b/tests/snapshots/test_derive_input__attr_with_mod_style_path_with_self.snap
@@ -0,0 +1,53 @@
+---
+created: "2019-03-11T05:40:04.790629386Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [
+        Attribute {
+            pound_token: Pound,
+            style: Outer,
+            bracket_token: Bracket,
+            path: Path {
+                leading_colon: None,
+                segments: [
+                    PathSegment {
+                        ident: Ident(
+                            foo
+                        ),
+                        arguments: None
+                    },
+                    Colon2,
+                    PathSegment {
+                        ident: Ident(
+                            self
+                        ),
+                        arguments: None
+                    }
+                ]
+            },
+            tts: TokenStream []
+        }
+    ],
+    vis: Inherited,
+    ident: Ident(
+        S
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unit,
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__attr_with_non_mod_style_path.snap b/tests/snapshots/test_derive_input__attr_with_non_mod_style_path.snap
new file mode 100644
index 0000000..fe0fa39
--- /dev/null
+++ b/tests/snapshots/test_derive_input__attr_with_non_mod_style_path.snap
@@ -0,0 +1,58 @@
+---
+created: "2019-03-11T05:40:04.790698962Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [
+        Attribute {
+            pound_token: Pound,
+            style: Outer,
+            bracket_token: Bracket,
+            path: Path {
+                leading_colon: None,
+                segments: [
+                    PathSegment {
+                        ident: Ident(
+                            inert
+                        ),
+                        arguments: None
+                    }
+                ]
+            },
+            tts: TokenStream [
+                Punct {
+                    op: '<',
+                    spacing: Alone
+                },
+                Ident {
+                    sym: T
+                },
+                Punct {
+                    op: '>',
+                    spacing: Alone
+                }
+            ]
+        }
+    ],
+    vis: Inherited,
+    ident: Ident(
+        S
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unit,
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__attr_with_path.snap b/tests/snapshots/test_derive_input__attr_with_path.snap
new file mode 100644
index 0000000..8ff18a2
--- /dev/null
+++ b/tests/snapshots/test_derive_input__attr_with_path.snap
@@ -0,0 +1,101 @@
+---
+created: "2019-03-11T05:40:04.790812796Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [
+        Attribute {
+            pound_token: Pound,
+            style: Outer,
+            bracket_token: Bracket,
+            path: Path {
+                leading_colon: Some(
+                    Colon2
+                ),
+                segments: [
+                    PathSegment {
+                        ident: Ident(
+                            attr_args
+                        ),
+                        arguments: None
+                    },
+                    Colon2,
+                    PathSegment {
+                        ident: Ident(
+                            identity
+                        ),
+                        arguments: None
+                    }
+                ]
+            },
+            tts: TokenStream [
+                Ident {
+                    sym: fn
+                },
+                Ident {
+                    sym: main
+                },
+                Group {
+                    delimiter: Parenthesis,
+                    stream: TokenStream []
+                },
+                Group {
+                    delimiter: Brace,
+                    stream: TokenStream [
+                        Ident {
+                            sym: assert_eq
+                        },
+                        Punct {
+                            op: '!',
+                            spacing: Alone
+                        },
+                        Group {
+                            delimiter: Parenthesis,
+                            stream: TokenStream [
+                                Ident {
+                                    sym: foo
+                                },
+                                Group {
+                                    delimiter: Parenthesis,
+                                    stream: TokenStream []
+                                },
+                                Punct {
+                                    op: ',',
+                                    spacing: Alone
+                                },
+                                Literal {
+                                    lit: "Hello, world!"
+                                }
+                            ]
+                        },
+                        Punct {
+                            op: ';',
+                            spacing: Alone
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    vis: Inherited,
+    ident: Ident(
+        Dummy
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unit,
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__enum-2.snap b/tests/snapshots/test_derive_input__enum-2.snap
new file mode 100644
index 0000000..f57e8ad
--- /dev/null
+++ b/tests/snapshots/test_derive_input__enum-2.snap
@@ -0,0 +1,28 @@
+---
+created: "2019-03-11T05:40:06.910167896Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+[
+    NameValue(
+        MetaNameValue {
+            ident: Ident(
+                doc
+            ),
+            eq_token: Eq,
+            lit: Str(
+                LitStr {
+                    token: Literal {
+                        lit: r" See the std::result module documentation for details."
+                    }
+                }
+            )
+        }
+    ),
+    Word(
+        Ident(
+            must_use
+        )
+    )
+]
diff --git a/tests/snapshots/test_derive_input__enum.snap b/tests/snapshots/test_derive_input__enum.snap
new file mode 100644
index 0000000..4baa91e
--- /dev/null
+++ b/tests/snapshots/test_derive_input__enum.snap
@@ -0,0 +1,260 @@
+---
+created: "2019-03-11T05:40:04.803840235Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [
+        Attribute {
+            pound_token: Pound,
+            style: Outer,
+            bracket_token: Bracket,
+            path: Path {
+                leading_colon: None,
+                segments: [
+                    PathSegment {
+                        ident: Ident(
+                            doc
+                        ),
+                        arguments: None
+                    }
+                ]
+            },
+            tts: TokenStream [
+                Punct {
+                    op: '=',
+                    spacing: Alone
+                },
+                Literal {
+                    lit: r" See the std::result module documentation for details."
+                }
+            ]
+        },
+        Attribute {
+            pound_token: Pound,
+            style: Outer,
+            bracket_token: Bracket,
+            path: Path {
+                leading_colon: None,
+                segments: [
+                    PathSegment {
+                        ident: Ident(
+                            must_use
+                        ),
+                        arguments: None
+                    }
+                ]
+            },
+            tts: TokenStream []
+        }
+    ],
+    vis: Public(
+        VisPublic {
+            pub_token: Pub
+        }
+    ),
+    ident: Ident(
+        Result
+    ),
+    generics: Generics {
+        lt_token: Some(
+            Lt
+        ),
+        params: [
+            Type(
+                TypeParam {
+                    attrs: [],
+                    ident: Ident(
+                        T
+                    ),
+                    colon_token: None,
+                    bounds: [],
+                    eq_token: None,
+                    default: None
+                }
+            ),
+            Comma,
+            Type(
+                TypeParam {
+                    attrs: [],
+                    ident: Ident(
+                        E
+                    ),
+                    colon_token: None,
+                    bounds: [],
+                    eq_token: None,
+                    default: None
+                }
+            )
+        ],
+        gt_token: Some(
+            Gt
+        ),
+        where_clause: None
+    },
+    data: Enum(
+        DataEnum {
+            enum_token: Enum,
+            brace_token: Brace,
+            variants: [
+                Variant {
+                    attrs: [],
+                    ident: Ident(
+                        Ok
+                    ),
+                    fields: Unnamed(
+                        FieldsUnnamed {
+                            paren_token: Paren,
+                            unnamed: [
+                                Field {
+                                    attrs: [],
+                                    vis: Inherited,
+                                    ident: None,
+                                    colon_token: None,
+                                    ty: Path(
+                                        TypePath {
+                                            qself: None,
+                                            path: Path {
+                                                leading_colon: None,
+                                                segments: [
+                                                    PathSegment {
+                                                        ident: Ident(
+                                                            T
+                                                        ),
+                                                        arguments: None
+                                                    }
+                                                ]
+                                            }
+                                        }
+                                    )
+                                }
+                            ]
+                        }
+                    ),
+                    discriminant: None
+                },
+                Comma,
+                Variant {
+                    attrs: [],
+                    ident: Ident(
+                        Err
+                    ),
+                    fields: Unnamed(
+                        FieldsUnnamed {
+                            paren_token: Paren,
+                            unnamed: [
+                                Field {
+                                    attrs: [],
+                                    vis: Inherited,
+                                    ident: None,
+                                    colon_token: None,
+                                    ty: Path(
+                                        TypePath {
+                                            qself: None,
+                                            path: Path {
+                                                leading_colon: None,
+                                                segments: [
+                                                    PathSegment {
+                                                        ident: Ident(
+                                                            E
+                                                        ),
+                                                        arguments: None
+                                                    }
+                                                ]
+                                            }
+                                        }
+                                    )
+                                }
+                            ]
+                        }
+                    ),
+                    discriminant: None
+                },
+                Comma,
+                Variant {
+                    attrs: [],
+                    ident: Ident(
+                        Surprise
+                    ),
+                    fields: Unit,
+                    discriminant: Some(
+                        (
+                            Eq,
+                            Lit(
+                                ExprLit {
+                                    attrs: [],
+                                    lit: Int(
+                                        LitInt {
+                                            token: Literal {
+                                                lit: 0isize
+                                            }
+                                        }
+                                    )
+                                }
+                            )
+                        )
+                    )
+                },
+                Comma,
+                Variant {
+                    attrs: [],
+                    ident: Ident(
+                        ProcMacroHack
+                    ),
+                    fields: Unit,
+                    discriminant: Some(
+                        (
+                            Eq,
+                            Field(
+                                ExprField {
+                                    attrs: [],
+                                    base: Tuple(
+                                        ExprTuple {
+                                            attrs: [],
+                                            paren_token: Paren,
+                                            elems: [
+                                                Lit(
+                                                    ExprLit {
+                                                        attrs: [],
+                                                        lit: Int(
+                                                            LitInt {
+                                                                token: Literal {
+                                                                    lit: 0
+                                                                }
+                                                            }
+                                                        )
+                                                    }
+                                                ),
+                                                Comma,
+                                                Lit(
+                                                    ExprLit {
+                                                        attrs: [],
+                                                        lit: Str(
+                                                            LitStr {
+                                                                token: Literal {
+                                                                    lit: "data"
+                                                                }
+                                                            }
+                                                        )
+                                                    }
+                                                )
+                                            ]
+                                        }
+                                    ),
+                                    dot_token: Dot,
+                                    member: Unnamed(
+                                        Index {
+                                            index: 0,
+                                            span: Span
+                                        }
+                                    )
+                                }
+                            )
+                        )
+                    )
+                }
+            ]
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__fields_on_named_struct-2.snap b/tests/snapshots/test_derive_input__fields_on_named_struct-2.snap
new file mode 100644
index 0000000..dc59f4b
--- /dev/null
+++ b/tests/snapshots/test_derive_input__fields_on_named_struct-2.snap
@@ -0,0 +1,68 @@
+---
+created: "2019-03-11T05:40:06.909636070Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+[
+    Field {
+        attrs: [],
+        vis: Inherited,
+        ident: Some(
+            Ident(
+                foo
+            )
+        ),
+        colon_token: Some(
+            Colon
+        ),
+        ty: Path(
+            TypePath {
+                qself: None,
+                path: Path {
+                    leading_colon: None,
+                    segments: [
+                        PathSegment {
+                            ident: Ident(
+                                i32
+                            ),
+                            arguments: None
+                        }
+                    ]
+                }
+            }
+        )
+    },
+    Field {
+        attrs: [],
+        vis: Public(
+            VisPublic {
+                pub_token: Pub
+            }
+        ),
+        ident: Some(
+            Ident(
+                bar
+            )
+        ),
+        colon_token: Some(
+            Colon
+        ),
+        ty: Path(
+            TypePath {
+                qself: None,
+                path: Path {
+                    leading_colon: None,
+                    segments: [
+                        PathSegment {
+                            ident: Ident(
+                                String
+                            ),
+                            arguments: None
+                        }
+                    ]
+                }
+            }
+        )
+    }
+]
diff --git a/tests/snapshots/test_derive_input__fields_on_named_struct.snap b/tests/snapshots/test_derive_input__fields_on_named_struct.snap
new file mode 100644
index 0000000..503ba05
--- /dev/null
+++ b/tests/snapshots/test_derive_input__fields_on_named_struct.snap
@@ -0,0 +1,94 @@
+---
+created: "2019-03-11T05:40:04.804489373Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [],
+    vis: Inherited,
+    ident: Ident(
+        S
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Named(
+                FieldsNamed {
+                    brace_token: Brace,
+                    named: [
+                        Field {
+                            attrs: [],
+                            vis: Inherited,
+                            ident: Some(
+                                Ident(
+                                    foo
+                                )
+                            ),
+                            colon_token: Some(
+                                Colon
+                            ),
+                            ty: Path(
+                                TypePath {
+                                    qself: None,
+                                    path: Path {
+                                        leading_colon: None,
+                                        segments: [
+                                            PathSegment {
+                                                ident: Ident(
+                                                    i32
+                                                ),
+                                                arguments: None
+                                            }
+                                        ]
+                                    }
+                                }
+                            )
+                        },
+                        Comma,
+                        Field {
+                            attrs: [],
+                            vis: Public(
+                                VisPublic {
+                                    pub_token: Pub
+                                }
+                            ),
+                            ident: Some(
+                                Ident(
+                                    bar
+                                )
+                            ),
+                            colon_token: Some(
+                                Colon
+                            ),
+                            ty: Path(
+                                TypePath {
+                                    qself: None,
+                                    path: Path {
+                                        leading_colon: None,
+                                        segments: [
+                                            PathSegment {
+                                                ident: Ident(
+                                                    String
+                                                ),
+                                                arguments: None
+                                            }
+                                        ]
+                                    }
+                                }
+                            )
+                        },
+                        Comma
+                    ]
+                }
+            ),
+            semi_token: None
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__fields_on_tuple_struct-2.snap b/tests/snapshots/test_derive_input__fields_on_tuple_struct-2.snap
new file mode 100644
index 0000000..89d2679
--- /dev/null
+++ b/tests/snapshots/test_derive_input__fields_on_tuple_struct-2.snap
@@ -0,0 +1,56 @@
+---
+created: "2019-03-11T05:40:06.909622097Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+[
+    Field {
+        attrs: [],
+        vis: Inherited,
+        ident: None,
+        colon_token: None,
+        ty: Path(
+            TypePath {
+                qself: None,
+                path: Path {
+                    leading_colon: None,
+                    segments: [
+                        PathSegment {
+                            ident: Ident(
+                                i32
+                            ),
+                            arguments: None
+                        }
+                    ]
+                }
+            }
+        )
+    },
+    Field {
+        attrs: [],
+        vis: Public(
+            VisPublic {
+                pub_token: Pub
+            }
+        ),
+        ident: None,
+        colon_token: None,
+        ty: Path(
+            TypePath {
+                qself: None,
+                path: Path {
+                    leading_colon: None,
+                    segments: [
+                        PathSegment {
+                            ident: Ident(
+                                String
+                            ),
+                            arguments: None
+                        }
+                    ]
+                }
+            }
+        )
+    }
+]
diff --git a/tests/snapshots/test_derive_input__fields_on_tuple_struct.snap b/tests/snapshots/test_derive_input__fields_on_tuple_struct.snap
new file mode 100644
index 0000000..f1e0acb
--- /dev/null
+++ b/tests/snapshots/test_derive_input__fields_on_tuple_struct.snap
@@ -0,0 +1,83 @@
+---
+created: "2019-03-11T05:40:04.805150017Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [],
+    vis: Inherited,
+    ident: Ident(
+        S
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unnamed(
+                FieldsUnnamed {
+                    paren_token: Paren,
+                    unnamed: [
+                        Field {
+                            attrs: [],
+                            vis: Inherited,
+                            ident: None,
+                            colon_token: None,
+                            ty: Path(
+                                TypePath {
+                                    qself: None,
+                                    path: Path {
+                                        leading_colon: None,
+                                        segments: [
+                                            PathSegment {
+                                                ident: Ident(
+                                                    i32
+                                                ),
+                                                arguments: None
+                                            }
+                                        ]
+                                    }
+                                }
+                            )
+                        },
+                        Comma,
+                        Field {
+                            attrs: [],
+                            vis: Public(
+                                VisPublic {
+                                    pub_token: Pub
+                                }
+                            ),
+                            ident: None,
+                            colon_token: None,
+                            ty: Path(
+                                TypePath {
+                                    qself: None,
+                                    path: Path {
+                                        leading_colon: None,
+                                        segments: [
+                                            PathSegment {
+                                                ident: Ident(
+                                                    String
+                                                ),
+                                                arguments: None
+                                            }
+                                        ]
+                                    }
+                                }
+                            )
+                        }
+                    ]
+                }
+            ),
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__fields_on_unit_struct.snap b/tests/snapshots/test_derive_input__fields_on_unit_struct.snap
new file mode 100644
index 0000000..801258a
--- /dev/null
+++ b/tests/snapshots/test_derive_input__fields_on_unit_struct.snap
@@ -0,0 +1,28 @@
+---
+created: "2019-03-11T05:40:04.807218906Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [],
+    vis: Inherited,
+    ident: Ident(
+        S
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unit,
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__pub_restricted.snap b/tests/snapshots/test_derive_input__pub_restricted.snap
new file mode 100644
index 0000000..c5ee320
--- /dev/null
+++ b/tests/snapshots/test_derive_input__pub_restricted.snap
@@ -0,0 +1,101 @@
+---
+created: "2019-03-11T05:40:04.817527335Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [],
+    vis: Restricted(
+        VisRestricted {
+            pub_token: Pub,
+            paren_token: Paren,
+            in_token: Some(
+                In
+            ),
+            path: Path {
+                leading_colon: None,
+                segments: [
+                    PathSegment {
+                        ident: Ident(
+                            m
+                        ),
+                        arguments: None
+                    }
+                ]
+            }
+        }
+    ),
+    ident: Ident(
+        Z
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unnamed(
+                FieldsUnnamed {
+                    paren_token: Paren,
+                    unnamed: [
+                        Field {
+                            attrs: [],
+                            vis: Restricted(
+                                VisRestricted {
+                                    pub_token: Pub,
+                                    paren_token: Paren,
+                                    in_token: Some(
+                                        In
+                                    ),
+                                    path: Path {
+                                        leading_colon: None,
+                                        segments: [
+                                            PathSegment {
+                                                ident: Ident(
+                                                    m
+                                                ),
+                                                arguments: None
+                                            },
+                                            Colon2,
+                                            PathSegment {
+                                                ident: Ident(
+                                                    n
+                                                ),
+                                                arguments: None
+                                            }
+                                        ]
+                                    }
+                                }
+                            ),
+                            ident: None,
+                            colon_token: None,
+                            ty: Path(
+                                TypePath {
+                                    qself: None,
+                                    path: Path {
+                                        leading_colon: None,
+                                        segments: [
+                                            PathSegment {
+                                                ident: Ident(
+                                                    u8
+                                                ),
+                                                arguments: None
+                                            }
+                                        ]
+                                    }
+                                }
+                            )
+                        }
+                    ]
+                }
+            ),
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__pub_restricted_crate.snap b/tests/snapshots/test_derive_input__pub_restricted_crate.snap
new file mode 100644
index 0000000..68da255
--- /dev/null
+++ b/tests/snapshots/test_derive_input__pub_restricted_crate.snap
@@ -0,0 +1,45 @@
+---
+created: "2019-03-11T05:40:04.817465809Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [],
+    vis: Restricted(
+        VisRestricted {
+            pub_token: Pub,
+            paren_token: Paren,
+            in_token: None,
+            path: Path {
+                leading_colon: None,
+                segments: [
+                    PathSegment {
+                        ident: Ident(
+                            crate
+                        ),
+                        arguments: None
+                    }
+                ]
+            }
+        }
+    ),
+    ident: Ident(
+        S
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unit,
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__pub_restricted_in_super.snap b/tests/snapshots/test_derive_input__pub_restricted_in_super.snap
new file mode 100644
index 0000000..afc0275
--- /dev/null
+++ b/tests/snapshots/test_derive_input__pub_restricted_in_super.snap
@@ -0,0 +1,47 @@
+---
+created: "2019-03-11T05:40:04.818690149Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [],
+    vis: Restricted(
+        VisRestricted {
+            pub_token: Pub,
+            paren_token: Paren,
+            in_token: Some(
+                In
+            ),
+            path: Path {
+                leading_colon: None,
+                segments: [
+                    PathSegment {
+                        ident: Ident(
+                            super
+                        ),
+                        arguments: None
+                    }
+                ]
+            }
+        }
+    ),
+    ident: Ident(
+        S
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unit,
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__pub_restricted_super.snap b/tests/snapshots/test_derive_input__pub_restricted_super.snap
new file mode 100644
index 0000000..b802079
--- /dev/null
+++ b/tests/snapshots/test_derive_input__pub_restricted_super.snap
@@ -0,0 +1,45 @@
+---
+created: "2019-03-11T05:40:04.828067085Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [],
+    vis: Restricted(
+        VisRestricted {
+            pub_token: Pub,
+            paren_token: Paren,
+            in_token: None,
+            path: Path {
+                leading_colon: None,
+                segments: [
+                    PathSegment {
+                        ident: Ident(
+                            super
+                        ),
+                        arguments: None
+                    }
+                ]
+            }
+        }
+    ),
+    ident: Ident(
+        S
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unit,
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__struct-2.snap b/tests/snapshots/test_derive_input__struct-2.snap
new file mode 100644
index 0000000..71778da
--- /dev/null
+++ b/tests/snapshots/test_derive_input__struct-2.snap
@@ -0,0 +1,31 @@
+---
+created: "2019-03-11T05:40:06.919215869Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            derive
+        ),
+        paren_token: Paren,
+        nested: [
+            Meta(
+                Word(
+                    Ident(
+                        Debug
+                    )
+                )
+            ),
+            Comma,
+            Meta(
+                Word(
+                    Ident(
+                        Clone
+                    )
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_derive_input__struct.snap b/tests/snapshots/test_derive_input__struct.snap
new file mode 100644
index 0000000..7b9e762
--- /dev/null
+++ b/tests/snapshots/test_derive_input__struct.snap
@@ -0,0 +1,161 @@
+---
+created: "2019-03-11T05:40:04.829338243Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [
+        Attribute {
+            pound_token: Pound,
+            style: Outer,
+            bracket_token: Bracket,
+            path: Path {
+                leading_colon: None,
+                segments: [
+                    PathSegment {
+                        ident: Ident(
+                            derive
+                        ),
+                        arguments: None
+                    }
+                ]
+            },
+            tts: TokenStream [
+                Group {
+                    delimiter: Parenthesis,
+                    stream: TokenStream [
+                        Ident {
+                            sym: Debug
+                        },
+                        Punct {
+                            op: ',',
+                            spacing: Alone
+                        },
+                        Ident {
+                            sym: Clone
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    vis: Public(
+        VisPublic {
+            pub_token: Pub
+        }
+    ),
+    ident: Ident(
+        Item
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Named(
+                FieldsNamed {
+                    brace_token: Brace,
+                    named: [
+                        Field {
+                            attrs: [],
+                            vis: Public(
+                                VisPublic {
+                                    pub_token: Pub
+                                }
+                            ),
+                            ident: Some(
+                                Ident(
+                                    ident
+                                )
+                            ),
+                            colon_token: Some(
+                                Colon
+                            ),
+                            ty: Path(
+                                TypePath {
+                                    qself: None,
+                                    path: Path {
+                                        leading_colon: None,
+                                        segments: [
+                                            PathSegment {
+                                                ident: Ident(
+                                                    Ident
+                                                ),
+                                                arguments: None
+                                            }
+                                        ]
+                                    }
+                                }
+                            )
+                        },
+                        Comma,
+                        Field {
+                            attrs: [],
+                            vis: Public(
+                                VisPublic {
+                                    pub_token: Pub
+                                }
+                            ),
+                            ident: Some(
+                                Ident(
+                                    attrs
+                                )
+                            ),
+                            colon_token: Some(
+                                Colon
+                            ),
+                            ty: Path(
+                                TypePath {
+                                    qself: None,
+                                    path: Path {
+                                        leading_colon: None,
+                                        segments: [
+                                            PathSegment {
+                                                ident: Ident(
+                                                    Vec
+                                                ),
+                                                arguments: AngleBracketed(
+                                                    AngleBracketedGenericArguments {
+                                                        colon2_token: None,
+                                                        lt_token: Lt,
+                                                        args: [
+                                                            Type(
+                                                                Path(
+                                                                    TypePath {
+                                                                        qself: None,
+                                                                        path: Path {
+                                                                            leading_colon: None,
+                                                                            segments: [
+                                                                                PathSegment {
+                                                                                    ident: Ident(
+                                                                                        Attribute
+                                                                                    ),
+                                                                                    arguments: None
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    }
+                                                                )
+                                                            )
+                                                        ],
+                                                        gt_token: Gt
+                                                    }
+                                                )
+                                            }
+                                        ]
+                                    }
+                                }
+                            )
+                        }
+                    ]
+                }
+            ),
+            semi_token: None
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__union.snap b/tests/snapshots/test_derive_input__union.snap
new file mode 100644
index 0000000..62a48d6
--- /dev/null
+++ b/tests/snapshots/test_derive_input__union.snap
@@ -0,0 +1,93 @@
+---
+created: "2019-03-11T05:40:04.829920492Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [],
+    vis: Inherited,
+    ident: Ident(
+        MaybeUninit
+    ),
+    generics: Generics {
+        lt_token: Some(
+            Lt
+        ),
+        params: [
+            Type(
+                TypeParam {
+                    attrs: [],
+                    ident: Ident(
+                        T
+                    ),
+                    colon_token: None,
+                    bounds: [],
+                    eq_token: None,
+                    default: None
+                }
+            )
+        ],
+        gt_token: Some(
+            Gt
+        ),
+        where_clause: None
+    },
+    data: Union(
+        DataUnion {
+            union_token: Union,
+            fields: FieldsNamed {
+                brace_token: Brace,
+                named: [
+                    Field {
+                        attrs: [],
+                        vis: Inherited,
+                        ident: Some(
+                            Ident(
+                                uninit
+                            )
+                        ),
+                        colon_token: Some(
+                            Colon
+                        ),
+                        ty: Tuple(
+                            TypeTuple {
+                                paren_token: Paren,
+                                elems: []
+                            }
+                        )
+                    },
+                    Comma,
+                    Field {
+                        attrs: [],
+                        vis: Inherited,
+                        ident: Some(
+                            Ident(
+                                value
+                            )
+                        ),
+                        colon_token: Some(
+                            Colon
+                        ),
+                        ty: Path(
+                            TypePath {
+                                qself: None,
+                                path: Path {
+                                    leading_colon: None,
+                                    segments: [
+                                        PathSegment {
+                                            ident: Ident(
+                                                T
+                                            ),
+                                            arguments: None
+                                        }
+                                    ]
+                                }
+                            }
+                        )
+                    }
+                ]
+            }
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__unit.snap b/tests/snapshots/test_derive_input__unit.snap
new file mode 100644
index 0000000..6837648
--- /dev/null
+++ b/tests/snapshots/test_derive_input__unit.snap
@@ -0,0 +1,28 @@
+---
+created: "2019-03-11T05:40:04.832138544Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [],
+    vis: Inherited,
+    ident: Ident(
+        Unit
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unit,
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_derive_input__vis_crate.snap b/tests/snapshots/test_derive_input__vis_crate.snap
new file mode 100644
index 0000000..8bea10a
--- /dev/null
+++ b/tests/snapshots/test_derive_input__vis_crate.snap
@@ -0,0 +1,32 @@
+---
+created: "2019-03-11T05:40:04.843066396Z"
+creator: insta@0.7.1
+source: tests/test_derive_input.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [],
+    vis: Crate(
+        VisCrate {
+            crate_token: Crate
+        }
+    ),
+    ident: Ident(
+        S
+    ),
+    generics: Generics {
+        lt_token: None,
+        params: [],
+        gt_token: None,
+        where_clause: None
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unit,
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_generics__fn_precedence_in_where_clause.snap b/tests/snapshots/test_generics__fn_precedence_in_where_clause.snap
new file mode 100644
index 0000000..b6fd4e7
--- /dev/null
+++ b/tests/snapshots/test_generics__fn_precedence_in_where_clause.snap
@@ -0,0 +1,143 @@
+---
+created: "2019-03-11T05:40:08.879764440Z"
+creator: insta@0.7.1
+source: tests/test_generics.rs
+expression: syntax_tree
+---
+ItemFn {
+    attrs: [],
+    vis: Inherited,
+    constness: None,
+    unsafety: None,
+    asyncness: None,
+    abi: None,
+    ident: Ident(
+        f
+    ),
+    decl: FnDecl {
+        fn_token: Fn,
+        generics: Generics {
+            lt_token: Some(
+                Lt
+            ),
+            params: [
+                Type(
+                    TypeParam {
+                        attrs: [],
+                        ident: Ident(
+                            G
+                        ),
+                        colon_token: None,
+                        bounds: [],
+                        eq_token: None,
+                        default: None
+                    }
+                )
+            ],
+            gt_token: Some(
+                Gt
+            ),
+            where_clause: Some(
+                WhereClause {
+                    where_token: Where,
+                    predicates: [
+                        Type(
+                            PredicateType {
+                                lifetimes: None,
+                                bounded_ty: Path(
+                                    TypePath {
+                                        qself: None,
+                                        path: Path {
+                                            leading_colon: None,
+                                            segments: [
+                                                PathSegment {
+                                                    ident: Ident(
+                                                        G
+                                                    ),
+                                                    arguments: None
+                                                }
+                                            ]
+                                        }
+                                    }
+                                ),
+                                colon_token: Colon,
+                                bounds: [
+                                    Trait(
+                                        TraitBound {
+                                            paren_token: None,
+                                            modifier: None,
+                                            lifetimes: None,
+                                            path: Path {
+                                                leading_colon: None,
+                                                segments: [
+                                                    PathSegment {
+                                                        ident: Ident(
+                                                            FnOnce
+                                                        ),
+                                                        arguments: Parenthesized(
+                                                            ParenthesizedGenericArguments {
+                                                                paren_token: Paren,
+                                                                inputs: [],
+                                                                output: Type(
+                                                                    RArrow,
+                                                                    Path(
+                                                                        TypePath {
+                                                                            qself: None,
+                                                                            path: Path {
+                                                                                leading_colon: None,
+                                                                                segments: [
+                                                                                    PathSegment {
+                                                                                        ident: Ident(
+                                                                                            i32
+                                                                                        ),
+                                                                                        arguments: None
+                                                                                    }
+                                                                                ]
+                                                                            }
+                                                                        }
+                                                                    )
+                                                                )
+                                                            }
+                                                        )
+                                                    }
+                                                ]
+                                            }
+                                        }
+                                    ),
+                                    Add,
+                                    Trait(
+                                        TraitBound {
+                                            paren_token: None,
+                                            modifier: None,
+                                            lifetimes: None,
+                                            path: Path {
+                                                leading_colon: None,
+                                                segments: [
+                                                    PathSegment {
+                                                        ident: Ident(
+                                                            Send
+                                                        ),
+                                                        arguments: None
+                                                    }
+                                                ]
+                                            }
+                                        }
+                                    )
+                                ]
+                            }
+                        ),
+                        Comma
+                    ]
+                }
+            )
+        },
+        paren_token: Paren,
+        inputs: [],
+        variadic: None,
+        output: Default
+    },
+    block: Block {
+        brace_token: Brace,
+        stmts: []
+    }
+}
diff --git a/tests/snapshots/test_generics__split_for_impl.snap b/tests/snapshots/test_generics__split_for_impl.snap
new file mode 100644
index 0000000..1c85362
--- /dev/null
+++ b/tests/snapshots/test_generics__split_for_impl.snap
@@ -0,0 +1,168 @@
+---
+created: "2019-03-11T05:40:08.879711571Z"
+creator: insta@0.7.1
+source: tests/test_generics.rs
+expression: syntax_tree
+---
+DeriveInput {
+    attrs: [],
+    vis: Inherited,
+    ident: Ident(
+        S
+    ),
+    generics: Generics {
+        lt_token: Some(
+            Lt
+        ),
+        params: [
+            Lifetime(
+                LifetimeDef {
+                    attrs: [],
+                    lifetime: Lifetime {
+                        apostrophe: Span,
+                        ident: Ident(
+                            a
+                        )
+                    },
+                    colon_token: None,
+                    bounds: []
+                }
+            ),
+            Comma,
+            Lifetime(
+                LifetimeDef {
+                    attrs: [],
+                    lifetime: Lifetime {
+                        apostrophe: Span,
+                        ident: Ident(
+                            b
+                        )
+                    },
+                    colon_token: Some(
+                        Colon
+                    ),
+                    bounds: [
+                        Lifetime {
+                            apostrophe: Span,
+                            ident: Ident(
+                                a
+                            )
+                        }
+                    ]
+                }
+            ),
+            Comma,
+            Type(
+                TypeParam {
+                    attrs: [
+                        Attribute {
+                            pound_token: Pound,
+                            style: Outer,
+                            bracket_token: Bracket,
+                            path: Path {
+                                leading_colon: None,
+                                segments: [
+                                    PathSegment {
+                                        ident: Ident(
+                                            may_dangle
+                                        ),
+                                        arguments: None
+                                    }
+                                ]
+                            },
+                            tts: TokenStream []
+                        }
+                    ],
+                    ident: Ident(
+                        T
+                    ),
+                    colon_token: Some(
+                        Colon
+                    ),
+                    bounds: [
+                        Lifetime(
+                            Lifetime {
+                                apostrophe: Span,
+                                ident: Ident(
+                                    a
+                                )
+                            }
+                        )
+                    ],
+                    eq_token: Some(
+                        Eq
+                    ),
+                    default: Some(
+                        Tuple(
+                            TypeTuple {
+                                paren_token: Paren,
+                                elems: []
+                            }
+                        )
+                    )
+                }
+            )
+        ],
+        gt_token: Some(
+            Gt
+        ),
+        where_clause: Some(
+            WhereClause {
+                where_token: Where,
+                predicates: [
+                    Type(
+                        PredicateType {
+                            lifetimes: None,
+                            bounded_ty: Path(
+                                TypePath {
+                                    qself: None,
+                                    path: Path {
+                                        leading_colon: None,
+                                        segments: [
+                                            PathSegment {
+                                                ident: Ident(
+                                                    T
+                                                ),
+                                                arguments: None
+                                            }
+                                        ]
+                                    }
+                                }
+                            ),
+                            colon_token: Colon,
+                            bounds: [
+                                Trait(
+                                    TraitBound {
+                                        paren_token: None,
+                                        modifier: None,
+                                        lifetimes: None,
+                                        path: Path {
+                                            leading_colon: None,
+                                            segments: [
+                                                PathSegment {
+                                                    ident: Ident(
+                                                        Debug
+                                                    ),
+                                                    arguments: None
+                                                }
+                                            ]
+                                        }
+                                    }
+                                )
+                            ]
+                        }
+                    )
+                ]
+            }
+        )
+    },
+    data: Struct(
+        DataStruct {
+            struct_token: Struct,
+            fields: Unit,
+            semi_token: Some(
+                Semi
+            )
+        }
+    )
+}
diff --git a/tests/snapshots/test_generics__ty_param_bound-2.snap b/tests/snapshots/test_generics__ty_param_bound-2.snap
new file mode 100644
index 0000000..6aded83
--- /dev/null
+++ b/tests/snapshots/test_generics__ty_param_bound-2.snap
@@ -0,0 +1,14 @@
+---
+created: "2019-03-11T05:40:10.830456179Z"
+creator: insta@0.7.1
+source: tests/test_generics.rs
+expression: syntax_tree
+---
+Lifetime(
+    Lifetime {
+        apostrophe: Span,
+        ident: Ident(
+            _
+        )
+    }
+)
diff --git a/tests/snapshots/test_generics__ty_param_bound-3.snap b/tests/snapshots/test_generics__ty_param_bound-3.snap
new file mode 100644
index 0000000..8df1133
--- /dev/null
+++ b/tests/snapshots/test_generics__ty_param_bound-3.snap
@@ -0,0 +1,24 @@
+---
+created: "2019-03-11T05:40:13.064709777Z"
+creator: insta@0.7.1
+source: tests/test_generics.rs
+expression: syntax_tree
+---
+Trait(
+    TraitBound {
+        paren_token: None,
+        modifier: None,
+        lifetimes: None,
+        path: Path {
+            leading_colon: None,
+            segments: [
+                PathSegment {
+                    ident: Ident(
+                        Debug
+                    ),
+                    arguments: None
+                }
+            ]
+        }
+    }
+)
diff --git a/tests/snapshots/test_generics__ty_param_bound-4.snap b/tests/snapshots/test_generics__ty_param_bound-4.snap
new file mode 100644
index 0000000..c2e5aab
--- /dev/null
+++ b/tests/snapshots/test_generics__ty_param_bound-4.snap
@@ -0,0 +1,26 @@
+---
+created: "2019-03-11T05:40:15.210326918Z"
+creator: insta@0.7.1
+source: tests/test_generics.rs
+expression: syntax_tree
+---
+Trait(
+    TraitBound {
+        paren_token: None,
+        modifier: Maybe(
+            Question
+        ),
+        lifetimes: None,
+        path: Path {
+            leading_colon: None,
+            segments: [
+                PathSegment {
+                    ident: Ident(
+                        Sized
+                    ),
+                    arguments: None
+                }
+            ]
+        }
+    }
+)
diff --git a/tests/snapshots/test_generics__ty_param_bound.snap b/tests/snapshots/test_generics__ty_param_bound.snap
new file mode 100644
index 0000000..a0e5d94
--- /dev/null
+++ b/tests/snapshots/test_generics__ty_param_bound.snap
@@ -0,0 +1,14 @@
+---
+created: "2019-03-11T05:40:08.879701944Z"
+creator: insta@0.7.1
+source: tests/test_generics.rs
+expression: syntax_tree
+---
+Lifetime(
+    Lifetime {
+        apostrophe: Span,
+        ident: Ident(
+            a
+        )
+    }
+)
diff --git a/tests/snapshots/test_generics__where_clause_at_end_of_input.snap b/tests/snapshots/test_generics__where_clause_at_end_of_input.snap
new file mode 100644
index 0000000..b45cc05
--- /dev/null
+++ b/tests/snapshots/test_generics__where_clause_at_end_of_input.snap
@@ -0,0 +1,10 @@
+---
+created: "2019-03-11T05:40:08.879661715Z"
+creator: insta@0.7.1
+source: tests/test_generics.rs
+expression: syntax_tree
+---
+WhereClause {
+    where_token: Where,
+    predicates: []
+}
diff --git a/tests/snapshots/test_grouping__grouping.snap b/tests/snapshots/test_grouping__grouping.snap
new file mode 100644
index 0000000..9336850
--- /dev/null
+++ b/tests/snapshots/test_grouping__grouping.snap
@@ -0,0 +1,84 @@
+---
+created: "2019-03-11T05:40:17.391725505Z"
+creator: insta@0.7.1
+source: tests/test_grouping.rs
+expression: syntax_tree
+---
+Binary(
+    ExprBinary {
+        attrs: [],
+        left: Lit(
+            ExprLit {
+                attrs: [],
+                lit: Int(
+                    LitInt {
+                        token: Literal {
+                            lit: 1i32
+                        }
+                    }
+                )
+            }
+        ),
+        op: Add(
+            Add
+        ),
+        right: Binary(
+            ExprBinary {
+                attrs: [],
+                left: Group(
+                    ExprGroup {
+                        attrs: [],
+                        group_token: Group,
+                        expr: Binary(
+                            ExprBinary {
+                                attrs: [],
+                                left: Lit(
+                                    ExprLit {
+                                        attrs: [],
+                                        lit: Int(
+                                            LitInt {
+                                                token: Literal {
+                                                    lit: 2i32
+                                                }
+                                            }
+                                        )
+                                    }
+                                ),
+                                op: Add(
+                                    Add
+                                ),
+                                right: Lit(
+                                    ExprLit {
+                                        attrs: [],
+                                        lit: Int(
+                                            LitInt {
+                                                token: Literal {
+                                                    lit: 3i32
+                                                }
+                                            }
+                                        )
+                                    }
+                                )
+                            }
+                        )
+                    }
+                ),
+                op: Mul(
+                    Star
+                ),
+                right: Lit(
+                    ExprLit {
+                        attrs: [],
+                        lit: Int(
+                            LitInt {
+                                token: Literal {
+                                    lit: 4i32
+                                }
+                            }
+                        )
+                    }
+                )
+            }
+        )
+    }
+)
diff --git a/tests/snapshots/test_meta__parse_meta_item_list_lit-2.snap b/tests/snapshots/test_meta__parse_meta_item_list_lit-2.snap
new file mode 100644
index 0000000..82dcbf7
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_meta_item_list_lit-2.snap
@@ -0,0 +1,25 @@
+---
+created: "2019-03-11T05:40:21.675781063Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Literal(
+                Int(
+                    LitInt {
+                        token: Literal {
+                            lit: 5
+                        }
+                    }
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_meta__parse_meta_item_list_lit.snap b/tests/snapshots/test_meta__parse_meta_item_list_lit.snap
new file mode 100644
index 0000000..c54a46b
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_meta_item_list_lit.snap
@@ -0,0 +1,23 @@
+---
+created: "2019-03-11T05:40:19.682551683Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+MetaList {
+    ident: Ident(
+        foo
+    ),
+    paren_token: Paren,
+    nested: [
+        Literal(
+            Int(
+                LitInt {
+                    token: Literal {
+                        lit: 5
+                    }
+                }
+            )
+        )
+    ]
+}
diff --git a/tests/snapshots/test_meta__parse_meta_item_multiple-2.snap b/tests/snapshots/test_meta__parse_meta_item_multiple-2.snap
new file mode 100644
index 0000000..2de3b50
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_meta_item_multiple-2.snap
@@ -0,0 +1,79 @@
+---
+created: "2019-03-11T05:40:21.675850965Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+List(
+    MetaList {
+        ident: Ident(
+            foo
+        ),
+        paren_token: Paren,
+        nested: [
+            Meta(
+                Word(
+                    Ident(
+                        word
+                    )
+                )
+            ),
+            Comma,
+            Meta(
+                NameValue(
+                    MetaNameValue {
+                        ident: Ident(
+                            name
+                        ),
+                        eq_token: Eq,
+                        lit: Int(
+                            LitInt {
+                                token: Literal {
+                                    lit: 5
+                                }
+                            }
+                        )
+                    }
+                )
+            ),
+            Comma,
+            Meta(
+                List(
+                    MetaList {
+                        ident: Ident(
+                            list
+                        ),
+                        paren_token: Paren,
+                        nested: [
+                            Meta(
+                                NameValue(
+                                    MetaNameValue {
+                                        ident: Ident(
+                                            name2
+                                        ),
+                                        eq_token: Eq,
+                                        lit: Int(
+                                            LitInt {
+                                                token: Literal {
+                                                    lit: 6
+                                                }
+                                            }
+                                        )
+                                    }
+                                )
+                            )
+                        ]
+                    }
+                )
+            ),
+            Comma,
+            Meta(
+                Word(
+                    Ident(
+                        word2
+                    )
+                )
+            )
+        ]
+    }
+)
diff --git a/tests/snapshots/test_meta__parse_meta_item_multiple.snap b/tests/snapshots/test_meta__parse_meta_item_multiple.snap
new file mode 100644
index 0000000..ec5fe57
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_meta_item_multiple.snap
@@ -0,0 +1,77 @@
+---
+created: "2019-03-11T05:40:19.682559314Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+MetaList {
+    ident: Ident(
+        foo
+    ),
+    paren_token: Paren,
+    nested: [
+        Meta(
+            Word(
+                Ident(
+                    word
+                )
+            )
+        ),
+        Comma,
+        Meta(
+            NameValue(
+                MetaNameValue {
+                    ident: Ident(
+                        name
+                    ),
+                    eq_token: Eq,
+                    lit: Int(
+                        LitInt {
+                            token: Literal {
+                                lit: 5
+                            }
+                        }
+                    )
+                }
+            )
+        ),
+        Comma,
+        Meta(
+            List(
+                MetaList {
+                    ident: Ident(
+                        list
+                    ),
+                    paren_token: Paren,
+                    nested: [
+                        Meta(
+                            NameValue(
+                                MetaNameValue {
+                                    ident: Ident(
+                                        name2
+                                    ),
+                                    eq_token: Eq,
+                                    lit: Int(
+                                        LitInt {
+                                            token: Literal {
+                                                lit: 6
+                                            }
+                                        }
+                                    )
+                                }
+                            )
+                        )
+                    ]
+                }
+            )
+        ),
+        Comma,
+        Meta(
+            Word(
+                Ident(
+                    word2
+                )
+            )
+        )
+    ]
+}
diff --git a/tests/snapshots/test_meta__parse_meta_item_word.snap b/tests/snapshots/test_meta__parse_meta_item_word.snap
new file mode 100644
index 0000000..4857569
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_meta_item_word.snap
@@ -0,0 +1,11 @@
+---
+created: "2019-03-11T05:40:19.682489939Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+Word(
+    Ident(
+        hello
+    )
+)
diff --git a/tests/snapshots/test_meta__parse_meta_name_value-2.snap b/tests/snapshots/test_meta__parse_meta_name_value-2.snap
new file mode 100644
index 0000000..23ab47f
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_meta_name_value-2.snap
@@ -0,0 +1,21 @@
+---
+created: "2019-03-11T05:40:21.675781065Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+NameValue(
+    MetaNameValue {
+        ident: Ident(
+            foo
+        ),
+        eq_token: Eq,
+        lit: Int(
+            LitInt {
+                token: Literal {
+                    lit: 5
+                }
+            }
+        )
+    }
+)
diff --git a/tests/snapshots/test_meta__parse_meta_name_value.snap b/tests/snapshots/test_meta__parse_meta_name_value.snap
new file mode 100644
index 0000000..aee596e
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_meta_name_value.snap
@@ -0,0 +1,19 @@
+---
+created: "2019-03-11T05:40:19.682552842Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+MetaNameValue {
+    ident: Ident(
+        foo
+    ),
+    eq_token: Eq,
+    lit: Int(
+        LitInt {
+            token: Literal {
+                lit: 5
+            }
+        }
+    )
+}
diff --git a/tests/snapshots/test_meta__parse_meta_name_value_with_bool-2.snap b/tests/snapshots/test_meta__parse_meta_name_value_with_bool-2.snap
new file mode 100644
index 0000000..261f86e
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_meta_name_value_with_bool-2.snap
@@ -0,0 +1,21 @@
+---
+created: "2019-03-11T05:40:21.676510552Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+NameValue(
+    MetaNameValue {
+        ident: Ident(
+            true
+        ),
+        eq_token: Eq,
+        lit: Int(
+            LitInt {
+                token: Literal {
+                    lit: 5
+                }
+            }
+        )
+    }
+)
diff --git a/tests/snapshots/test_meta__parse_meta_name_value_with_bool.snap b/tests/snapshots/test_meta__parse_meta_name_value_with_bool.snap
new file mode 100644
index 0000000..4749ee6
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_meta_name_value_with_bool.snap
@@ -0,0 +1,19 @@
+---
+created: "2019-03-11T05:40:19.694865579Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+MetaNameValue {
+    ident: Ident(
+        true
+    ),
+    eq_token: Eq,
+    lit: Int(
+        LitInt {
+            token: Literal {
+                lit: 5
+            }
+        }
+    )
+}
diff --git a/tests/snapshots/test_meta__parse_meta_name_value_with_keyword-2.snap b/tests/snapshots/test_meta__parse_meta_name_value_with_keyword-2.snap
new file mode 100644
index 0000000..1b57a4d
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_meta_name_value_with_keyword-2.snap
@@ -0,0 +1,21 @@
+---
+created: "2019-03-11T05:40:21.687855159Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+NameValue(
+    MetaNameValue {
+        ident: Ident(
+            static
+        ),
+        eq_token: Eq,
+        lit: Int(
+            LitInt {
+                token: Literal {
+                    lit: 5
+                }
+            }
+        )
+    }
+)
diff --git a/tests/snapshots/test_meta__parse_meta_name_value_with_keyword.snap b/tests/snapshots/test_meta__parse_meta_name_value_with_keyword.snap
new file mode 100644
index 0000000..7dc4873
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_meta_name_value_with_keyword.snap
@@ -0,0 +1,19 @@
+---
+created: "2019-03-11T05:40:19.694905983Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+MetaNameValue {
+    ident: Ident(
+        static
+    ),
+    eq_token: Eq,
+    lit: Int(
+        LitInt {
+            token: Literal {
+                lit: 5
+            }
+        }
+    )
+}
diff --git a/tests/snapshots/test_meta__parse_nested_meta-2.snap b/tests/snapshots/test_meta__parse_nested_meta-2.snap
new file mode 100644
index 0000000..cf77f99
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_nested_meta-2.snap
@@ -0,0 +1,35 @@
+---
+created: "2019-03-11T05:40:21.688020363Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+Meta(
+    List(
+        MetaList {
+            ident: Ident(
+                list
+            ),
+            paren_token: Paren,
+            nested: [
+                Meta(
+                    NameValue(
+                        MetaNameValue {
+                            ident: Ident(
+                                name2
+                            ),
+                            eq_token: Eq,
+                            lit: Int(
+                                LitInt {
+                                    token: Literal {
+                                        lit: 6
+                                    }
+                                }
+                            )
+                        }
+                    )
+                )
+            ]
+        }
+    )
+)
diff --git a/tests/snapshots/test_meta__parse_nested_meta.snap b/tests/snapshots/test_meta__parse_nested_meta.snap
new file mode 100644
index 0000000..44bbb88
--- /dev/null
+++ b/tests/snapshots/test_meta__parse_nested_meta.snap
@@ -0,0 +1,15 @@
+---
+created: "2019-03-11T05:40:19.695971093Z"
+creator: insta@0.7.1
+source: tests/test_meta.rs
+expression: syntax_tree
+---
+Literal(
+    Int(
+        LitInt {
+            token: Literal {
+                lit: 5
+            }
+        }
+    )
+)
diff --git a/tests/snapshots/test_token_trees__struct.snap b/tests/snapshots/test_token_trees__struct.snap
new file mode 100644
index 0000000..834c72b
--- /dev/null
+++ b/tests/snapshots/test_token_trees__struct.snap
@@ -0,0 +1,94 @@
+---
+created: "2019-03-11T05:40:49.182513206Z"
+creator: insta@0.7.1
+source: tests/test_token_trees.rs
+expression: syntax_tree
+---
+TokenStream [
+    Punct {
+        op: '#',
+        spacing: Alone
+    },
+    Group {
+        delimiter: Bracket,
+        stream: TokenStream [
+            Ident {
+                sym: derive
+            },
+            Group {
+                delimiter: Parenthesis,
+                stream: TokenStream [
+                    Ident {
+                        sym: Debug
+                    },
+                    Punct {
+                        op: ',',
+                        spacing: Alone
+                    },
+                    Ident {
+                        sym: Clone
+                    }
+                ]
+            }
+        ]
+    },
+    Ident {
+        sym: pub
+    },
+    Ident {
+        sym: struct
+    },
+    Ident {
+        sym: Item
+    },
+    Group {
+        delimiter: Brace,
+        stream: TokenStream [
+            Ident {
+                sym: pub
+            },
+            Ident {
+                sym: ident
+            },
+            Punct {
+                op: ':',
+                spacing: Alone
+            },
+            Ident {
+                sym: Ident
+            },
+            Punct {
+                op: ',',
+                spacing: Alone
+            },
+            Ident {
+                sym: pub
+            },
+            Ident {
+                sym: attrs
+            },
+            Punct {
+                op: ':',
+                spacing: Alone
+            },
+            Ident {
+                sym: Vec
+            },
+            Punct {
+                op: '<',
+                spacing: Alone
+            },
+            Ident {
+                sym: Attribute
+            },
+            Punct {
+                op: '>',
+                spacing: Joint
+            },
+            Punct {
+                op: ',',
+                spacing: Alone
+            }
+        ]
+    }
+]
diff --git a/tests/test_asyncness.rs b/tests/test_asyncness.rs
index 3d59e6b..4d7ae7d 100644
--- a/tests/test_asyncness.rs
+++ b/tests/test_asyncness.rs
@@ -1,63 +1,20 @@
-extern crate proc_macro2;
 extern crate syn;
 
 mod features;
 
-use proc_macro2::Span;
-use syn::punctuated::Punctuated;
-use syn::{Block, Expr, ExprBlock, ExprClosure, FnDecl, Ident, ItemFn, ReturnType, Visibility};
+#[macro_use]
+mod macros;
+
+use syn::{Expr, Item};
 
 #[test]
 fn test_async_fn() {
-    let raw = "async fn process() {}";
-
-    let expected = ItemFn {
-        attrs: vec![],
-        vis: Visibility::Inherited,
-        constness: None,
-        unsafety: None,
-        asyncness: Some(Default::default()),
-        abi: None,
-        ident: Ident::new("process", Span::call_site()),
-        decl: Box::new(FnDecl {
-            fn_token: Default::default(),
-            generics: Default::default(),
-            paren_token: Default::default(),
-            inputs: Punctuated::new(),
-            variadic: None,
-            output: ReturnType::Default,
-        }),
-        block: Box::new(Block {
-            brace_token: Default::default(),
-            stmts: vec![],
-        }),
-    };
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
+    let code = "async fn process() {}";
+    snapshot!(code as Item);
 }
 
 #[test]
 fn test_async_closure() {
-    let raw = "async || {}";
-
-    let expected = Expr::Closure(ExprClosure {
-        attrs: vec![],
-        movability: None,
-        asyncness: Some(Default::default()),
-        capture: None,
-        or1_token: Default::default(),
-        inputs: Punctuated::new(),
-        or2_token: Default::default(),
-        output: ReturnType::Default,
-        body: Box::new(Expr::Block(ExprBlock {
-            attrs: vec![],
-            label: None,
-            block: Block {
-                brace_token: Default::default(),
-                stmts: vec![],
-            },
-        })),
-    });
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
+    let code = "async || {}";
+    snapshot!(code as Expr);
 }
diff --git a/tests/test_attribute.rs b/tests/test_attribute.rs
new file mode 100644
index 0000000..ab21544
--- /dev/null
+++ b/tests/test_attribute.rs
@@ -0,0 +1,67 @@
+extern crate syn;
+
+mod features;
+
+#[macro_use]
+mod macros;
+
+use syn::parse::Parser;
+use syn::Attribute;
+
+#[test]
+fn test_meta_item_word() {
+    test("#[foo]")
+}
+
+#[test]
+fn test_meta_item_name_value() {
+    test("#[foo = 5]")
+}
+
+#[test]
+fn test_meta_item_bool_value() {
+    test("#[foo = true]");
+    test("#[foo = false]")
+}
+
+#[test]
+fn test_meta_item_list_lit() {
+    test("#[foo(5)]")
+}
+
+#[test]
+fn test_meta_item_list_word() {
+    test("#[foo(bar)]")
+}
+
+#[test]
+fn test_meta_item_list_name_value() {
+    test("#[foo(bar = 5)]")
+}
+
+#[test]
+fn test_meta_item_list_bool_value() {
+    test("#[foo(bar = true)]")
+}
+
+#[test]
+fn test_meta_item_multiple() {
+    test("#[foo(word, name = 5, list(name2 = 6), word2)]")
+}
+
+#[test]
+fn test_bool_lit() {
+    test("#[foo(true)]")
+}
+
+fn test(input: &str) {
+    let attrs = Attribute::parse_outer.parse_str(input).unwrap();
+
+    assert_eq!(attrs.len(), 1);
+
+    let attr = attrs.into_iter().next().unwrap();
+    let interpret = snapshot!(attr.interpret_meta().unwrap());
+    let parse = snapshot!(attr.parse_meta().unwrap());
+
+    assert_eq!(interpret, parse);
+}
diff --git a/tests/test_derive_input.rs b/tests/test_derive_input.rs
index 63bdc23..dc1b872 100644
--- a/tests/test_derive_input.rs
+++ b/tests/test_derive_input.rs
@@ -1,225 +1,54 @@
-extern crate proc_macro2;
+extern crate quote;
 extern crate syn;
 
 mod features;
 
-use proc_macro2::Delimiter::{Brace, Parenthesis};
-use proc_macro2::*;
-use syn::punctuated::Punctuated;
-use syn::*;
-
-use std::iter::FromIterator;
-
 #[macro_use]
 mod macros;
 
-fn op(c: char) -> TokenTree {
-    Punct::new(c, Spacing::Alone).into()
-}
-
-fn lit<T: Into<Literal>>(t: T) -> TokenTree {
-    t.into().into()
-}
-
-fn ident(sym: &str) -> Ident {
-    Ident::new(sym, Span::call_site())
-}
-
-fn word(sym: &str) -> TokenTree {
-    ident(sym).into()
-}
-
-fn delimited(delim: Delimiter, tokens: Vec<TokenTree>) -> TokenTree {
-    Group::new(delim, tokens.into_iter().collect()).into()
-}
+use quote::quote;
+use syn::{Data, DeriveInput};
 
 #[test]
 fn test_unit() {
-    let raw = "struct Unit;";
-
-    let expected = DeriveInput {
-        ident: ident("Unit"),
-        vis: Visibility::Inherited,
-        attrs: Vec::new(),
-        generics: Generics::default(),
-        data: Data::Struct(DataStruct {
-            semi_token: Some(Default::default()),
-            struct_token: Default::default(),
-            fields: Fields::Unit,
-        }),
+    let code = quote! {
+        struct Unit;
     };
 
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
+    snapshot!(code as DeriveInput);
 }
 
 #[test]
 fn test_struct() {
-    let raw = "
+    let code = quote! {
         #[derive(Debug, Clone)]
         pub struct Item {
             pub ident: Ident,
             pub attrs: Vec<Attribute>
         }
-    ";
-
-    let expected = DeriveInput {
-        ident: ident("Item"),
-        vis: Visibility::Public(VisPublic {
-            pub_token: Default::default(),
-        }),
-        attrs: vec![Attribute {
-            bracket_token: Default::default(),
-            pound_token: Default::default(),
-            style: AttrStyle::Outer,
-            path: ident("derive").into(),
-            tts: TokenStream::from_iter(vec![delimited(
-                Parenthesis,
-                vec![word("Debug"), op(','), word("Clone")],
-            )]),
-        }],
-        generics: Generics::default(),
-        data: Data::Struct(DataStruct {
-            semi_token: None,
-            struct_token: Default::default(),
-            fields: Fields::Named(FieldsNamed {
-                brace_token: Default::default(),
-                named: punctuated![
-                    Field {
-                        ident: Some(ident("ident")),
-                        colon_token: Some(Default::default()),
-                        vis: Visibility::Public(VisPublic {
-                            pub_token: Default::default(),
-                        }),
-                        attrs: Vec::new(),
-                        ty: TypePath {
-                            qself: None,
-                            path: ident("Ident").into(),
-                        }
-                        .into(),
-                    },
-                    Field {
-                        ident: Some(ident("attrs")),
-                        colon_token: Some(Default::default()),
-                        vis: Visibility::Public(VisPublic {
-                            pub_token: Default::default(),
-                        }),
-                        attrs: Vec::new(),
-                        ty: TypePath {
-                            qself: None,
-                            path: Path {
-                                leading_colon: None,
-                                segments: punctuated![PathSegment {
-                                    ident: ident("Vec"),
-                                    arguments: PathArguments::AngleBracketed(
-                                        AngleBracketedGenericArguments {
-                                            colon2_token: None,
-                                            lt_token: Default::default(),
-                                            args: punctuated![GenericArgument::Type(Type::from(
-                                                TypePath {
-                                                    qself: None,
-                                                    path: ident("Attribute").into(),
-                                                }
-                                            )),],
-                                            gt_token: Default::default(),
-                                        },
-                                    ),
-                                },],
-                            },
-                        }
-                        .into(),
-                    },
-                ],
-            }),
-        }),
     };
 
-    let actual = syn::parse_str(raw).unwrap();
+    let actual = snapshot!(code as DeriveInput);
 
-    assert_eq!(expected, actual);
-
-    let expected_meta_item: Meta = MetaList {
-        ident: ident("derive"),
-        paren_token: Default::default(),
-        nested: punctuated![
-            NestedMeta::Meta(Meta::Word(ident("Debug"))),
-            NestedMeta::Meta(Meta::Word(ident("Clone"))),
-        ],
-    }
-    .into();
-
-    assert_eq!(
-        expected_meta_item,
-        actual.attrs[0].interpret_meta().unwrap()
-    );
+    snapshot!(actual.attrs[0].interpret_meta().unwrap());
 }
 
 #[test]
 fn test_union() {
-    let raw = "
+    let code = quote! {
         union MaybeUninit<T> {
             uninit: (),
             value: T
         }
-    ";
-
-    let expected = DeriveInput {
-        ident: ident("MaybeUninit"),
-        vis: Visibility::Inherited,
-        attrs: Vec::new(),
-        generics: Generics {
-            lt_token: Some(Default::default()),
-            params: punctuated![GenericParam::Type(TypeParam {
-                attrs: Vec::new(),
-                ident: ident("T"),
-                bounds: Default::default(),
-                default: None,
-                colon_token: None,
-                eq_token: None,
-            }),],
-            gt_token: Some(Default::default()),
-            where_clause: None,
-        },
-        data: Data::Union(DataUnion {
-            union_token: Default::default(),
-            fields: FieldsNamed {
-                brace_token: Default::default(),
-                named: punctuated![
-                    Field {
-                        ident: Some(ident("uninit")),
-                        colon_token: Some(Default::default()),
-                        vis: Visibility::Inherited,
-                        attrs: Vec::new(),
-                        ty: TypeTuple {
-                            paren_token: Default::default(),
-                            elems: Punctuated::new(),
-                        }
-                        .into(),
-                    },
-                    Field {
-                        ident: Some(ident("value")),
-                        colon_token: Some(Default::default()),
-                        vis: Visibility::Inherited,
-                        attrs: Vec::new(),
-                        ty: TypePath {
-                            qself: None,
-                            path: ident("T").into(),
-                        }
-                        .into(),
-                    },
-                ],
-            },
-        }),
     };
 
-    let actual = syn::parse_str(raw).unwrap();
-
-    assert_eq!(expected, actual);
+    snapshot!(code as DeriveInput);
 }
 
 #[test]
 #[cfg(feature = "full")]
 fn test_enum() {
-    let raw = r#"
+    let code = quote! {
         /// See the std::result module documentation for details.
         #[must_use]
         pub enum Result<T, E> {
@@ -231,304 +60,52 @@
             // in the style of https://github.com/dtolnay/proc-macro-hack
             ProcMacroHack = (0, "data").0
         }
-    "#;
-
-    let expected = DeriveInput {
-        ident: ident("Result"),
-        vis: Visibility::Public(VisPublic {
-            pub_token: Default::default(),
-        }),
-        attrs: vec![
-            Attribute {
-                bracket_token: Default::default(),
-                pound_token: Default::default(),
-                style: AttrStyle::Outer,
-                path: ident("doc").into(),
-                tts: TokenStream::from_iter(vec![
-                    op('='),
-                    lit(Literal::string(
-                        " See the std::result module documentation for details.",
-                    )),
-                ]),
-            },
-            Attribute {
-                bracket_token: Default::default(),
-                pound_token: Default::default(),
-                style: AttrStyle::Outer,
-                path: ident("must_use").into(),
-                tts: TokenStream::new(),
-            },
-        ],
-        generics: Generics {
-            lt_token: Some(Default::default()),
-            params: punctuated![
-                GenericParam::Type(TypeParam {
-                    attrs: Vec::new(),
-                    ident: ident("T"),
-                    bounds: Default::default(),
-                    default: None,
-                    colon_token: None,
-                    eq_token: None,
-                }),
-                GenericParam::Type(TypeParam {
-                    attrs: Vec::new(),
-                    ident: ident("E"),
-                    bounds: Default::default(),
-                    colon_token: None,
-                    eq_token: None,
-                    default: None,
-                }),
-            ],
-            gt_token: Some(Default::default()),
-            where_clause: None,
-        },
-        data: Data::Enum(DataEnum {
-            variants: punctuated![
-                Variant {
-                    ident: ident("Ok"),
-                    attrs: Vec::new(),
-                    fields: Fields::Unnamed(FieldsUnnamed {
-                        paren_token: Default::default(),
-                        unnamed: punctuated![Field {
-                            colon_token: None,
-                            ident: None,
-                            vis: Visibility::Inherited,
-                            attrs: Vec::new(),
-                            ty: TypePath {
-                                qself: None,
-                                path: ident("T").into(),
-                            }
-                            .into(),
-                        },],
-                    }),
-                    discriminant: None,
-                },
-                Variant {
-                    ident: ident("Err"),
-                    attrs: Vec::new(),
-                    fields: Fields::Unnamed(FieldsUnnamed {
-                        paren_token: Default::default(),
-                        unnamed: punctuated![Field {
-                            ident: None,
-                            colon_token: None,
-                            vis: Visibility::Inherited,
-                            attrs: Vec::new(),
-                            ty: TypePath {
-                                qself: None,
-                                path: ident("E").into(),
-                            }
-                            .into(),
-                        },],
-                    }),
-                    discriminant: None,
-                },
-                Variant {
-                    ident: ident("Surprise"),
-                    attrs: Vec::new(),
-                    fields: Fields::Unit,
-                    discriminant: Some((
-                        Default::default(),
-                        Expr::Lit(ExprLit {
-                            attrs: Vec::new(),
-                            lit: Lit::Int(LitInt::new(0, IntSuffix::Isize, Span::call_site())),
-                        }),
-                    )),
-                },
-                Variant {
-                    ident: ident("ProcMacroHack"),
-                    attrs: Vec::new(),
-                    fields: Fields::Unit,
-                    discriminant: Some((
-                        Default::default(),
-                        Expr::Field(ExprField {
-                            attrs: Vec::new(),
-                            base: Box::new(Expr::Tuple(ExprTuple {
-                                attrs: Vec::new(),
-                                paren_token: Default::default(),
-                                elems: punctuated![
-                                    Expr::Lit(ExprLit {
-                                        attrs: Vec::new(),
-                                        lit: Lit::Int(LitInt::new(
-                                            0,
-                                            IntSuffix::None,
-                                            Span::call_site()
-                                        )),
-                                    }),
-                                    Expr::Lit(ExprLit {
-                                        attrs: Vec::new(),
-                                        lit: Lit::Str(LitStr::new("data", Span::call_site())),
-                                    }),
-                                ],
-                            })),
-                            dot_token: Default::default(),
-                            member: Member::Unnamed(Index {
-                                index: 0,
-                                span: Span::call_site(),
-                            }),
-                        }),
-                    )),
-                },
-            ],
-            brace_token: Default::default(),
-            enum_token: Default::default(),
-        }),
     };
 
-    let actual = syn::parse_str(raw).unwrap();
+    let actual = snapshot!(code as DeriveInput);
 
-    assert_eq!(expected, actual);
-
-    let expected_meta_items = vec![
-        MetaNameValue {
-            ident: ident("doc"),
-            eq_token: Default::default(),
-            lit: Lit::Str(LitStr::new(
-                " See the std::result module documentation for details.",
-                Span::call_site(),
-            )),
-        }
-        .into(),
-        Meta::Word(ident("must_use")),
-    ];
-
-    let actual_meta_items: Vec<_> = actual
+    let meta_items: Vec<_> = actual
         .attrs
         .into_iter()
         .map(|attr| attr.interpret_meta().unwrap())
         .collect();
 
-    assert_eq!(expected_meta_items, actual_meta_items);
+    snapshot!(meta_items);
 }
 
 #[test]
 fn test_attr_with_path() {
-    let raw = r#"
+    let code = quote! {
         #[::attr_args::identity
             fn main() { assert_eq!(foo(), "Hello, world!"); }]
         struct Dummy;
-    "#;
-
-    let expected = DeriveInput {
-        ident: ident("Dummy"),
-        vis: Visibility::Inherited,
-        attrs: vec![Attribute {
-            bracket_token: Default::default(),
-            pound_token: Default::default(),
-            style: AttrStyle::Outer,
-            path: Path {
-                leading_colon: Some(Default::default()),
-                segments: punctuated![
-                    PathSegment::from(ident("attr_args")),
-                    PathSegment::from(ident("identity")),
-                ],
-            },
-            tts: TokenStream::from_iter(vec![
-                word("fn"),
-                word("main"),
-                delimited(Parenthesis, vec![]),
-                delimited(
-                    Brace,
-                    vec![
-                        word("assert_eq"),
-                        op('!'),
-                        delimited(
-                            Parenthesis,
-                            vec![
-                                word("foo"),
-                                delimited(Parenthesis, vec![]),
-                                op(','),
-                                lit(Literal::string("Hello, world!")),
-                            ],
-                        ),
-                        op(';'),
-                    ],
-                ),
-            ]),
-        }],
-        generics: Generics::default(),
-        data: Data::Struct(DataStruct {
-            fields: Fields::Unit,
-            semi_token: Some(Default::default()),
-            struct_token: Default::default(),
-        }),
     };
 
-    let actual = syn::parse_str(raw).unwrap();
-
-    assert_eq!(expected, actual);
+    let actual = snapshot!(code as DeriveInput);
 
     assert!(actual.attrs[0].interpret_meta().is_none());
 }
 
 #[test]
 fn test_attr_with_non_mod_style_path() {
-    let raw = r#"
+    let code = quote! {
         #[inert <T>]
         struct S;
-    "#;
-
-    let expected = DeriveInput {
-        ident: ident("S"),
-        vis: Visibility::Inherited,
-        attrs: vec![Attribute {
-            bracket_token: Default::default(),
-            pound_token: Default::default(),
-            style: AttrStyle::Outer,
-            path: Path {
-                leading_colon: None,
-                segments: punctuated![PathSegment::from(ident("inert"))],
-            },
-            tts: TokenStream::from_iter(vec![op('<'), word("T"), op('>')]),
-        }],
-        generics: Generics::default(),
-        data: Data::Struct(DataStruct {
-            fields: Fields::Unit,
-            semi_token: Some(Default::default()),
-            struct_token: Default::default(),
-        }),
     };
 
-    let actual = syn::parse_str(raw).unwrap();
-
-    assert_eq!(expected, actual);
+    let actual = snapshot!(code as DeriveInput);
 
     assert!(actual.attrs[0].interpret_meta().is_none());
 }
 
 #[test]
 fn test_attr_with_mod_style_path_with_self() {
-    let raw = r#"
+    let code = quote! {
         #[foo::self]
         struct S;
-    "#;
-
-    let expected = DeriveInput {
-        ident: ident("S"),
-        vis: Visibility::Inherited,
-        attrs: vec![Attribute {
-            bracket_token: Default::default(),
-            pound_token: Default::default(),
-            style: AttrStyle::Outer,
-            path: Path {
-                leading_colon: None,
-                segments: punctuated![
-                    PathSegment::from(ident("foo")),
-                    PathSegment::from(ident("self")),
-                ],
-            },
-            tts: TokenStream::new(),
-        }],
-        generics: Generics::default(),
-        data: Data::Struct(DataStruct {
-            fields: Fields::Unit,
-            semi_token: Some(Default::default()),
-            struct_token: Default::default(),
-        }),
     };
 
-    let actual = syn::parse_str(raw).unwrap();
-
-    assert_eq!(expected, actual);
+    let actual = snapshot!(code as DeriveInput);
 
     assert!(actual.attrs[0].interpret_meta().is_none());
 }
@@ -536,274 +113,106 @@
 #[test]
 fn test_pub_restricted() {
     // Taken from tests/rust/src/test/ui/resolve/auxiliary/privacy-struct-ctor.rs
-    let raw = r#"
+    let code = quote! {
         pub(in m) struct Z(pub(in m::n) u8);
-    "#;
-
-    let expected = DeriveInput {
-        ident: ident("Z"),
-        vis: Visibility::Restricted(VisRestricted {
-            path: Box::new(ident("m").into()),
-            in_token: Some(Default::default()),
-            paren_token: Default::default(),
-            pub_token: Default::default(),
-        }),
-        attrs: vec![],
-        generics: Generics::default(),
-        data: Data::Struct(DataStruct {
-            fields: Fields::Unnamed(FieldsUnnamed {
-                paren_token: Default::default(),
-                unnamed: punctuated![Field {
-                    ident: None,
-                    vis: Visibility::Restricted(VisRestricted {
-                        path: Box::new(Path {
-                            leading_colon: None,
-                            segments: punctuated![
-                                PathSegment::from(ident("m")),
-                                PathSegment::from(ident("n")),
-                            ],
-                        }),
-                        in_token: Some(Default::default()),
-                        paren_token: Default::default(),
-                        pub_token: Default::default(),
-                    }),
-                    colon_token: None,
-                    attrs: vec![],
-                    ty: TypePath {
-                        qself: None,
-                        path: ident("u8").into(),
-                    }
-                    .into(),
-                },],
-            }),
-            semi_token: Some(Default::default()),
-            struct_token: Default::default(),
-        }),
     };
 
-    let actual = syn::parse_str(raw).unwrap();
-
-    assert_eq!(expected, actual);
+    snapshot!(code as DeriveInput);
 }
 
 #[test]
 fn test_vis_crate() {
-    let raw = r#"
+    let code = quote! {
         crate struct S;
-    "#;
-
-    let expected = DeriveInput {
-        ident: ident("S"),
-        vis: Visibility::Crate(VisCrate {
-            crate_token: Default::default(),
-        }),
-        attrs: vec![],
-        generics: Generics::default(),
-        data: Data::Struct(DataStruct {
-            semi_token: Some(Default::default()),
-            struct_token: Default::default(),
-            fields: Fields::Unit,
-        }),
     };
 
-    let actual = syn::parse_str(raw).unwrap();
-
-    assert_eq!(expected, actual);
+    snapshot!(code as DeriveInput);
 }
 
 #[test]
 fn test_pub_restricted_crate() {
-    let raw = r#"
+    let code = quote! {
         pub(crate) struct S;
-    "#;
-
-    let expected = DeriveInput {
-        ident: ident("S"),
-        vis: Visibility::Restricted(VisRestricted {
-            pub_token: Default::default(),
-            paren_token: Default::default(),
-            in_token: None,
-            path: Box::new(ident("crate").into()),
-        }),
-        attrs: vec![],
-        generics: Generics::default(),
-        data: Data::Struct(DataStruct {
-            semi_token: Some(Default::default()),
-            struct_token: Default::default(),
-            fields: Fields::Unit,
-        }),
     };
 
-    let actual = syn::parse_str(raw).unwrap();
-
-    assert_eq!(expected, actual);
+    snapshot!(code as DeriveInput);
 }
 
 #[test]
 fn test_pub_restricted_super() {
-    let raw = r#"
+    let code = quote! {
         pub(super) struct S;
-    "#;
-
-    let expected = DeriveInput {
-        ident: ident("S"),
-        vis: Visibility::Restricted(VisRestricted {
-            path: Box::new(ident("super").into()),
-            in_token: None,
-            paren_token: Default::default(),
-            pub_token: Default::default(),
-        }),
-        attrs: vec![],
-        generics: Generics::default(),
-        data: Data::Struct(DataStruct {
-            semi_token: Some(Default::default()),
-            struct_token: Default::default(),
-            fields: Fields::Unit,
-        }),
     };
 
-    let actual = syn::parse_str(raw).unwrap();
-
-    assert_eq!(expected, actual);
+    snapshot!(code as DeriveInput);
 }
 
 #[test]
 fn test_pub_restricted_in_super() {
-    let raw = r#"
+    let code = quote! {
         pub(in super) struct S;
-    "#;
-
-    let expected = DeriveInput {
-        ident: ident("S"),
-        vis: Visibility::Restricted(VisRestricted {
-            path: Box::new(ident("super").into()),
-            in_token: Some(Default::default()),
-            paren_token: Default::default(),
-            pub_token: Default::default(),
-        }),
-        attrs: vec![],
-        generics: Generics::default(),
-        data: Data::Struct(DataStruct {
-            semi_token: Some(Default::default()),
-            struct_token: Default::default(),
-            fields: Fields::Unit,
-        }),
     };
 
-    let actual = syn::parse_str(raw).unwrap();
-
-    assert_eq!(expected, actual);
+    snapshot!(code as DeriveInput);
 }
 
 #[test]
 fn test_fields_on_unit_struct() {
-    let raw = "struct S;";
-    let struct_body = match syn::parse_str::<DeriveInput>(raw).unwrap().data {
-        Data::Struct(body) => body,
-        _ => panic!("expected a struct"),
+    let code = quote! {
+        struct S;
     };
 
-    assert_eq!(0, struct_body.fields.iter().count());
+    let actual = snapshot!(code as DeriveInput);
+
+    match actual.data {
+        Data::Struct(data) => {
+            assert_eq!(0, data.fields.iter().count());
+        }
+        _ => panic!("expected a struct"),
+    }
 }
 
 #[test]
 fn test_fields_on_named_struct() {
-    let raw = "struct S {
-        foo: i32,
-        pub bar: String,
-    }";
-    let struct_body = match syn::parse_str::<DeriveInput>(raw).unwrap().data {
-        Data::Struct(body) => body,
-        _ => panic!("expected a struct"),
+    let code = quote! {
+        struct S {
+            foo: i32,
+            pub bar: String,
+        }
     };
 
-    let expected = vec![
-        Field {
-            attrs: vec![],
-            vis: Visibility::Inherited,
-            ident: Some(ident("foo")),
-            colon_token: Some(Default::default()),
-            ty: syn::parse_str("i32").unwrap(),
-        },
-        Field {
-            attrs: vec![],
-            vis: Visibility::Public(VisPublic {
-                pub_token: Default::default(),
-            }),
-            ident: Some(ident("bar")),
-            colon_token: Some(Default::default()),
-            ty: syn::parse_str("String").unwrap(),
-        },
-    ];
-    let expected = expected.iter().collect::<Vec<_>>();
+    let actual = snapshot!(code as DeriveInput);
 
-    assert_eq!(expected, struct_body.fields.iter().collect::<Vec<_>>());
+    match actual.data {
+        Data::Struct(data) => {
+            snapshot!(data.fields.iter().collect::<Vec<_>>());
+        }
+        _ => panic!("expected a struct"),
+    }
 }
 
 #[test]
 fn test_fields_on_tuple_struct() {
-    let raw = "struct S(i32, pub String);";
-    let struct_body = match syn::parse_str::<DeriveInput>(raw).unwrap().data {
-        Data::Struct(body) => body,
-        _ => panic!("expected a struct"),
+    let code = quote! {
+        struct S(i32, pub String);
     };
 
-    let expected = vec![
-        Field {
-            attrs: vec![],
-            vis: Visibility::Inherited,
-            ident: None,
-            colon_token: None,
-            ty: syn::parse_str("i32").unwrap(),
-        },
-        Field {
-            attrs: vec![],
-            vis: Visibility::Public(VisPublic {
-                pub_token: Default::default(),
-            }),
-            ident: None,
-            colon_token: None,
-            ty: syn::parse_str("String").unwrap(),
-        },
-    ];
-    let expected = expected.iter().collect::<Vec<_>>();
+    let actual = snapshot!(code as DeriveInput);
 
-    assert_eq!(expected, struct_body.fields.iter().collect::<Vec<_>>());
+    match actual.data {
+        Data::Struct(data) => {
+            snapshot!(data.fields.iter().collect::<Vec<_>>());
+        }
+        _ => panic!("expected a struct"),
+    }
 }
 
 #[test]
 fn test_ambiguous_crate() {
-    // The field type is `(crate::X)` not `crate (::X)`.
-    let raw = "struct S(crate::X);";
-
-    let expected = DeriveInput {
-        ident: ident("S"),
-        vis: Visibility::Inherited,
-        attrs: vec![],
-        generics: Generics::default(),
-        data: Data::Struct(DataStruct {
-            struct_token: Default::default(),
-            fields: Fields::Unnamed(FieldsUnnamed {
-                paren_token: Default::default(),
-                unnamed: punctuated![Field {
-                    attrs: Vec::new(),
-                    vis: Visibility::Inherited,
-                    ident: None,
-                    colon_token: None,
-                    ty: Type::Path(TypePath {
-                        qself: None,
-                        path: Path {
-                            leading_colon: None,
-                            segments: punctuated![ident("crate").into(), ident("X").into(),],
-                        },
-                    }),
-                }],
-            }),
-            semi_token: Some(Default::default()),
-        }),
+    let code = quote! {
+        // The field type is `(crate::X)` not `crate (::X)`.
+        struct S(crate::X);
     };
 
-    let actual = syn::parse_str(raw).unwrap();
-
-    assert_eq!(expected, actual);
+    snapshot!(code as DeriveInput);
 }
diff --git a/tests/test_generics.rs b/tests/test_generics.rs
index 841d6c6..112215a 100644
--- a/tests/test_generics.rs
+++ b/tests/test_generics.rs
@@ -1,156 +1,89 @@
-#![recursion_limit = "1024"]
-
-extern crate syn;
-use syn::*;
-
-#[macro_use]
 extern crate quote;
+extern crate syn;
 
-extern crate proc_macro2;
-use proc_macro2::{Ident, Span, TokenStream};
+mod features;
 
 #[macro_use]
 mod macros;
 
-mod features;
-
-fn ident(s: &str) -> Ident {
-    Ident::new(s, Span::call_site())
-}
+use quote::quote;
+use syn::{DeriveInput, ItemFn, TypeParamBound, WhereClause, WherePredicate};
 
 #[test]
 fn test_split_for_impl() {
-    // <'a, 'b: 'a, #[may_dangle] T: 'a = ()> where T: Debug
-    let generics = Generics {
-        gt_token: Some(Default::default()),
-        lt_token: Some(Default::default()),
-        params: punctuated![
-            GenericParam::Lifetime(LifetimeDef {
-                attrs: Default::default(),
-                lifetime: Lifetime::new("'a", Span::call_site()),
-                bounds: Default::default(),
-                colon_token: None,
-            }),
-            GenericParam::Lifetime(LifetimeDef {
-                attrs: Default::default(),
-                lifetime: Lifetime::new("'b", Span::call_site()),
-                bounds: punctuated![Lifetime::new("'a", Span::call_site())],
-                colon_token: Some(token::Colon::default()),
-            }),
-            GenericParam::Type(TypeParam {
-                attrs: vec![Attribute {
-                    bracket_token: Default::default(),
-                    pound_token: Default::default(),
-                    style: AttrStyle::Outer,
-                    path: ident("may_dangle").into(),
-                    tts: TokenStream::new(),
-                }],
-                ident: ident("T"),
-                bounds: punctuated![TypeParamBound::Lifetime(Lifetime::new(
-                    "'a",
-                    Span::call_site()
-                )),],
-                default: Some(
-                    TypeTuple {
-                        elems: Default::default(),
-                        paren_token: Default::default(),
-                    }
-                    .into(),
-                ),
-                colon_token: Some(Default::default()),
-                eq_token: Default::default(),
-            }),
-        ],
-        where_clause: Some(WhereClause {
-            where_token: Default::default(),
-            predicates: punctuated![WherePredicate::Type(PredicateType {
-                lifetimes: None,
-                colon_token: Default::default(),
-                bounded_ty: TypePath {
-                    qself: None,
-                    path: ident("T").into(),
-                }
-                .into(),
-                bounds: punctuated![TypeParamBound::Trait(TraitBound {
-                    paren_token: None,
-                    modifier: TraitBoundModifier::None,
-                    lifetimes: None,
-                    path: ident("Debug").into(),
-                }),],
-            }),],
-        }),
+    let code = quote! {
+        struct S<'a, 'b: 'a, #[may_dangle] T: 'a = ()> where T: Debug;
     };
 
+    let actual = snapshot!(code as DeriveInput);
+
+    let generics = actual.generics;
     let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
-    let tokens = quote! {
+
+    let generated = quote! {
         impl #impl_generics MyTrait for Test #ty_generics #where_clause {}
     };
-    let expected = concat!(
-        "impl < 'a , 'b : 'a , # [ may_dangle ] T : 'a > ",
-        "MyTrait for Test < 'a , 'b , T > ",
-        "where T : Debug { }"
-    );
-    assert_eq!(expected, tokens.to_string());
+    let expected = quote! {
+        impl<'a, 'b: 'a, #[may_dangle] T: 'a> MyTrait
+        for Test<'a, 'b, T>
+        where
+            T: Debug
+        {}
+    };
+    assert_eq!(generated.to_string(), expected.to_string());
 
     let turbofish = ty_generics.as_turbofish();
-    let tokens = quote! {
+    let generated = quote! {
         Test #turbofish
     };
-    let expected = "Test :: < 'a , 'b , T >";
-    assert_eq!(expected, tokens.to_string());
+    let expected = quote! {
+        Test::<'a, 'b, T>
+    };
+    assert_eq!(generated.to_string(), expected.to_string());
 }
 
 #[test]
 fn test_ty_param_bound() {
     let tokens = quote!('a);
-    let expected = TypeParamBound::Lifetime(Lifetime::new("'a", Span::call_site()));
-    assert_eq!(expected, syn::parse2::<TypeParamBound>(tokens).unwrap());
+    snapshot!(tokens as TypeParamBound);
 
     let tokens = quote!('_);
-    println!("{:?}", tokens);
-    let expected = TypeParamBound::Lifetime(Lifetime::new("'_", Span::call_site()));
-    assert_eq!(expected, syn::parse2::<TypeParamBound>(tokens).unwrap());
+    snapshot!(tokens as TypeParamBound);
 
     let tokens = quote!(Debug);
-    let expected = TypeParamBound::Trait(TraitBound {
-        paren_token: None,
-        modifier: TraitBoundModifier::None,
-        lifetimes: None,
-        path: ident("Debug").into(),
-    });
-    assert_eq!(expected, syn::parse2::<TypeParamBound>(tokens).unwrap());
+    snapshot!(tokens as TypeParamBound);
 
     let tokens = quote!(?Sized);
-    let expected = TypeParamBound::Trait(TraitBound {
-        paren_token: None,
-        modifier: TraitBoundModifier::Maybe(Default::default()),
-        lifetimes: None,
-        path: ident("Sized").into(),
-    });
-    assert_eq!(expected, syn::parse2::<TypeParamBound>(tokens).unwrap());
+    snapshot!(tokens as TypeParamBound);
 }
 
 #[test]
 fn test_fn_precedence_in_where_clause() {
     // This should parse as two separate bounds, `FnOnce() -> i32` and `Send` - not
     // `FnOnce() -> (i32 + Send)`.
-    let sig = quote! {
+    let code = quote! {
         fn f<G>()
         where
             G: FnOnce() -> i32 + Send,
         {
         }
     };
-    let fun = syn::parse2::<ItemFn>(sig).unwrap();
-    let where_clause = fun.decl.generics.where_clause.as_ref().unwrap();
+
+    let actual = snapshot!(code as ItemFn);
+
+    let where_clause = actual.decl.generics.where_clause.as_ref().unwrap();
     assert_eq!(where_clause.predicates.len(), 1);
-    let predicate = match where_clause.predicates[0] {
-        WherePredicate::Type(ref pred) => pred,
+
+    let predicate = match &where_clause.predicates[0] {
+        WherePredicate::Type(pred) => pred,
         _ => panic!("wrong predicate kind"),
     };
+
     assert_eq!(predicate.bounds.len(), 2, "{:#?}", predicate.bounds);
+
     let first_bound = &predicate.bounds[0];
     assert_eq!(quote!(#first_bound).to_string(), "FnOnce ( ) -> i32");
+
     let second_bound = &predicate.bounds[1];
     assert_eq!(quote!(#second_bound).to_string(), "Send");
 }
@@ -160,6 +93,7 @@
     let tokens = quote! {
         where
     };
-    let where_clause = syn::parse2::<WhereClause>(tokens).unwrap();
+
+    let where_clause = snapshot!(tokens as WhereClause);
     assert_eq!(where_clause.predicates.len(), 0);
 }
diff --git a/tests/test_grouping.rs b/tests/test_grouping.rs
index 7f362d1..df309ad 100644
--- a/tests/test_grouping.rs
+++ b/tests/test_grouping.rs
@@ -1,70 +1,34 @@
-#![recursion_limit = "1024"]
-
-#[macro_use]
-extern crate syn;
-use syn::token::Group;
-use syn::{BinOp, Expr, ExprBinary, ExprGroup, ExprLit, Lit};
-
 extern crate proc_macro2;
-use proc_macro2::*;
+extern crate syn;
 
 mod features;
 
-fn expr<T: Into<Expr>>(t: T) -> Expr {
-    t.into()
-}
+#[macro_use]
+mod macros;
 
-fn lit<T: Into<Literal>>(t: T) -> Expr {
-    Expr::Lit(ExprLit {
-        attrs: Vec::new(),
-        lit: Lit::new(t.into()),
-    })
-}
+use proc_macro2::{Delimiter, Group, Literal, Punct, Spacing, TokenStream, TokenTree};
+use syn::Expr;
+
+use std::iter::FromIterator;
 
 #[test]
 fn test_grouping() {
-    let raw: TokenStream = vec![
+    let tokens: TokenStream = TokenStream::from_iter(vec![
         TokenTree::Literal(Literal::i32_suffixed(1)),
         TokenTree::Punct(Punct::new('+', Spacing::Alone)),
-        TokenTree::Group(proc_macro2::Group::new(
+        TokenTree::Group(Group::new(
             Delimiter::None,
-            vec![
+            TokenStream::from_iter(vec![
                 TokenTree::Literal(Literal::i32_suffixed(2)),
                 TokenTree::Punct(Punct::new('+', Spacing::Alone)),
                 TokenTree::Literal(Literal::i32_suffixed(3)),
-            ]
-            .into_iter()
-            .collect(),
+            ]),
         )),
         TokenTree::Punct(Punct::new('*', Spacing::Alone)),
         TokenTree::Literal(Literal::i32_suffixed(4)),
-    ]
-    .into_iter()
-    .collect();
+    ]);
 
-    assert_eq!(raw.to_string(), "1i32 +  2i32 + 3i32  * 4i32");
+    assert_eq!(tokens.to_string(), "1i32 +  2i32 + 3i32  * 4i32");
 
-    assert_eq!(
-        syn::parse2::<syn::Expr>(raw).unwrap(),
-        expr(ExprBinary {
-            attrs: Vec::new(),
-            left: Box::new(lit(Literal::i32_suffixed(1))),
-            op: BinOp::Add(<Token![+]>::default()),
-            right: Box::new(expr(ExprBinary {
-                attrs: Vec::new(),
-                left: Box::new(expr(ExprGroup {
-                    attrs: Vec::new(),
-                    group_token: Group::default(),
-                    expr: Box::new(expr(ExprBinary {
-                        attrs: Vec::new(),
-                        left: Box::new(lit(Literal::i32_suffixed(2))),
-                        op: BinOp::Add(<Token![+]>::default()),
-                        right: Box::new(lit(Literal::i32_suffixed(3))),
-                    })),
-                })),
-                op: BinOp::Mul(<Token![*]>::default()),
-                right: Box::new(lit(Literal::i32_suffixed(4))),
-            })),
-        })
-    );
+    snapshot!(tokens as Expr);
 }
diff --git a/tests/test_meta.rs b/tests/test_meta.rs
new file mode 100644
index 0000000..4fb35da
--- /dev/null
+++ b/tests/test_meta.rs
@@ -0,0 +1,61 @@
+extern crate syn;
+
+mod features;
+
+#[macro_use]
+mod macros;
+
+use syn::parse::Parse;
+use syn::{Meta, MetaList, MetaNameValue, NestedMeta};
+use std::fmt::Debug;
+
+#[test]
+fn test_parse_meta_item_word() {
+    let code = "hello";
+
+    snapshot!(code as Meta);
+}
+
+#[test]
+fn test_parse_meta_name_value() {
+    test::<MetaNameValue>("foo = 5");
+}
+
+#[test]
+fn test_parse_meta_name_value_with_keyword() {
+    test::<MetaNameValue>("static = 5");
+}
+
+#[test]
+fn test_parse_meta_name_value_with_bool() {
+    test::<MetaNameValue>("true = 5");
+}
+
+#[test]
+fn test_parse_meta_item_list_lit() {
+    test::<MetaList>("foo(5)");
+}
+
+#[test]
+fn test_parse_meta_item_multiple() {
+    test::<MetaList>("foo(word, name = 5, list(name2 = 6), word2)");
+}
+
+#[test]
+fn test_parse_nested_meta() {
+    let code = "5";
+    snapshot!(code as NestedMeta);
+
+    let code = "list(name2 = 6)";
+    snapshot!(code as NestedMeta);
+}
+
+fn test<T>(input: &str)
+where
+    T: Parse + Into<Meta> + Debug,
+{
+    let inner = snapshot!(input as T);
+    let meta = snapshot!(input as Meta);
+
+    assert_eq!(meta, inner.into());
+}
diff --git a/tests/test_meta_item.rs b/tests/test_meta_item.rs
deleted file mode 100644
index 40f42bc..0000000
--- a/tests/test_meta_item.rs
+++ /dev/null
@@ -1,339 +0,0 @@
-extern crate proc_macro2;
-extern crate quote;
-extern crate syn;
-
-mod features;
-
-use proc_macro2::{Ident, Literal, Span};
-use syn::parse::Parser;
-use syn::*;
-
-#[macro_use]
-mod macros;
-
-fn lit<T: Into<Literal>>(t: T) -> Lit {
-    Lit::new(t.into())
-}
-
-fn ident(s: &str) -> Ident {
-    Ident::new(s, Span::call_site())
-}
-
-#[test]
-fn test_meta_item_word() {
-    run_test("#[foo]", Meta::Word(ident("foo")))
-}
-
-#[test]
-fn test_meta_item_name_value() {
-    run_test(
-        "#[foo = 5]",
-        MetaNameValue {
-            ident: ident("foo").into(),
-            eq_token: Default::default(),
-            lit: lit(Literal::i32_unsuffixed(5)),
-        },
-    )
-}
-
-#[test]
-fn test_meta_item_bool_value() {
-    run_test(
-        "#[foo = true]",
-        MetaNameValue {
-            ident: ident("foo").into(),
-            eq_token: Default::default(),
-            lit: Lit::Bool(LitBool {
-                value: true,
-                span: Span::call_site(),
-            }),
-        },
-    );
-    run_test(
-        "#[foo = false]",
-        MetaNameValue {
-            ident: ident("foo").into(),
-            eq_token: Default::default(),
-            lit: Lit::Bool(LitBool {
-                value: false,
-                span: Span::call_site(),
-            }),
-        },
-    )
-}
-
-#[test]
-fn test_meta_item_list_lit() {
-    run_test(
-        "#[foo(5)]",
-        MetaList {
-            ident: ident("foo").into(),
-            paren_token: Default::default(),
-            nested: punctuated![NestedMeta::Literal(lit(Literal::i32_unsuffixed(5)))],
-        },
-    )
-}
-
-#[test]
-fn test_meta_item_list_word() {
-    run_test(
-        "#[foo(bar)]",
-        MetaList {
-            ident: ident("foo").into(),
-            paren_token: Default::default(),
-            nested: punctuated![NestedMeta::Meta(Meta::Word(ident("bar").into()))],
-        },
-    )
-}
-
-#[test]
-fn test_meta_item_list_name_value() {
-    run_test(
-        "#[foo(bar = 5)]",
-        MetaList {
-            ident: ident("foo").into(),
-            paren_token: Default::default(),
-            nested: punctuated![NestedMeta::Meta(
-                MetaNameValue {
-                    ident: ident("bar").into(),
-                    eq_token: Default::default(),
-                    lit: lit(Literal::i32_unsuffixed(5)),
-                }
-                .into(),
-            )],
-        },
-    )
-}
-
-#[test]
-fn test_meta_item_list_bool_value() {
-    run_test(
-        "#[foo(bar = true)]",
-        MetaList {
-            ident: ident("foo").into(),
-            paren_token: Default::default(),
-            nested: punctuated![NestedMeta::Meta(
-                MetaNameValue {
-                    ident: ident("bar").into(),
-                    eq_token: Default::default(),
-                    lit: Lit::Bool(LitBool {
-                        value: true,
-                        span: Span::call_site()
-                    }),
-                }
-                .into(),
-            )],
-        },
-    )
-}
-
-#[test]
-fn test_meta_item_multiple() {
-    run_test(
-        "#[foo(word, name = 5, list(name2 = 6), word2)]",
-        MetaList {
-            ident: ident("foo").into(),
-            paren_token: Default::default(),
-            nested: punctuated![
-                NestedMeta::Meta(Meta::Word(ident("word").into())),
-                NestedMeta::Meta(
-                    MetaNameValue {
-                        ident: ident("name").into(),
-                        eq_token: Default::default(),
-                        lit: lit(Literal::i32_unsuffixed(5)),
-                    }
-                    .into(),
-                ),
-                NestedMeta::Meta(
-                    MetaList {
-                        ident: ident("list").into(),
-                        paren_token: Default::default(),
-                        nested: punctuated![NestedMeta::Meta(
-                            MetaNameValue {
-                                ident: ident("name2").into(),
-                                eq_token: Default::default(),
-                                lit: lit(Literal::i32_unsuffixed(6)),
-                            }
-                            .into(),
-                        )],
-                    }
-                    .into(),
-                ),
-                NestedMeta::Meta(Meta::Word(ident("word2").into())),
-            ],
-        },
-    )
-}
-
-#[test]
-fn test_bool_lit() {
-    run_test(
-        "#[foo(true)]",
-        MetaList {
-            ident: ident("foo").into(),
-            paren_token: Default::default(),
-            nested: punctuated![NestedMeta::Literal(Lit::Bool(LitBool {
-                value: true,
-                span: Span::call_site(),
-            }))],
-        },
-    )
-}
-
-#[test]
-fn test_parse_meta_item_word() {
-    let raw = "hello";
-
-    let expected = Meta::Word(ident("hello"));
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-}
-
-#[test]
-fn test_parse_meta_name_value() {
-    let raw = "foo = 5";
-
-    let expected = MetaNameValue {
-        ident: ident("foo").into(),
-        eq_token: Default::default(),
-        lit: lit(Literal::i32_unsuffixed(5)),
-    };
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-
-    let expected = Meta::NameValue(expected);
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-}
-
-#[test]
-fn test_parse_meta_name_value_with_keyword() {
-    let raw = "static = 5";
-
-    let expected = MetaNameValue {
-        ident: ident("static").into(),
-        eq_token: Default::default(),
-        lit: lit(Literal::i32_unsuffixed(5)),
-    };
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-
-    let expected = Meta::NameValue(expected);
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-}
-
-#[test]
-fn test_parse_meta_name_value_with_bool() {
-    let raw = "true = 5";
-
-    let expected = MetaNameValue {
-        ident: ident("true").into(),
-        eq_token: Default::default(),
-        lit: lit(Literal::i32_unsuffixed(5)),
-    };
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-
-    let expected = Meta::NameValue(expected);
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-}
-
-#[test]
-fn test_parse_meta_item_list_lit() {
-    let raw = "foo(5)";
-
-    let expected = MetaList {
-        ident: ident("foo").into(),
-        paren_token: Default::default(),
-        nested: punctuated![NestedMeta::Literal(lit(Literal::i32_unsuffixed(5)))],
-    };
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-
-    let expected = Meta::List(expected);
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-}
-
-#[test]
-fn test_parse_meta_item_multiple() {
-    let raw = "foo(word, name = 5, list(name2 = 6), word2)";
-
-    let expected = MetaList {
-        ident: ident("foo").into(),
-        paren_token: Default::default(),
-        nested: punctuated![
-            NestedMeta::Meta(Meta::Word(ident("word").into())),
-            NestedMeta::Meta(
-                MetaNameValue {
-                    ident: ident("name").into(),
-                    eq_token: Default::default(),
-                    lit: lit(Literal::i32_unsuffixed(5)),
-                }
-                .into(),
-            ),
-            NestedMeta::Meta(
-                MetaList {
-                    ident: ident("list").into(),
-                    paren_token: Default::default(),
-                    nested: punctuated![NestedMeta::Meta(
-                        MetaNameValue {
-                            ident: ident("name2").into(),
-                            eq_token: Default::default(),
-                            lit: lit(Literal::i32_unsuffixed(6)),
-                        }
-                        .into(),
-                    )],
-                }
-                .into(),
-            ),
-            NestedMeta::Meta(Meta::Word(ident("word2").into())),
-        ],
-    };
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-
-    let expected = Meta::List(expected);
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-}
-
-#[test]
-fn test_parse_nested_meta() {
-    let raw = "5";
-
-    let expected = NestedMeta::Literal(lit(Literal::i32_unsuffixed(5)));
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-
-    let raw = "list(name2 = 6)";
-
-    let expected = NestedMeta::Meta(
-        MetaList {
-            ident: ident("list").into(),
-            paren_token: Default::default(),
-            nested: punctuated![NestedMeta::Meta(
-                MetaNameValue {
-                    ident: ident("name2").into(),
-                    eq_token: Default::default(),
-                    lit: lit(Literal::i32_unsuffixed(6)),
-                }
-                .into(),
-            )],
-        }
-        .into(),
-    );
-
-    assert_eq!(expected, syn::parse_str(raw).unwrap());
-}
-
-fn run_test<T: Into<Meta>>(input: &str, expected: T) {
-    let attrs = Attribute::parse_outer.parse_str(input).unwrap();
-    assert_eq!(attrs.len(), 1);
-    let attr = attrs.into_iter().next().unwrap();
-    let expected = expected.into();
-    assert_eq!(expected, attr.interpret_meta().unwrap());
-    assert_eq!(expected, attr.parse_meta().unwrap());
-}
diff --git a/tests/test_pat.rs b/tests/test_pat.rs
index c5423d9..1343aa6 100644
--- a/tests/test_pat.rs
+++ b/tests/test_pat.rs
@@ -1,13 +1,15 @@
-#[macro_use]
 extern crate quote;
 extern crate syn;
 
 mod features;
 
+use quote::quote;
+use syn::Pat;
+
 #[test]
 fn test_pat_ident() {
     match syn::parse2(quote!(self)).unwrap() {
-        syn::Pat::Ident(_) => (),
+        Pat::Ident(_) => (),
         value => panic!("expected PatIdent, got {:?}", value),
     }
 }
@@ -15,7 +17,7 @@
 #[test]
 fn test_pat_path() {
     match syn::parse2(quote!(self::CONST)).unwrap() {
-        syn::Pat::Path(_) => (),
+        Pat::Path(_) => (),
         value => panic!("expected PatPath, got {:?}", value),
     }
 }
diff --git a/tests/test_token_trees.rs b/tests/test_token_trees.rs
index a927875..6e2d2dd 100644
--- a/tests/test_token_trees.rs
+++ b/tests/test_token_trees.rs
@@ -1,33 +1,19 @@
 extern crate proc_macro2;
-#[macro_use]
 extern crate quote;
 extern crate syn;
 
 mod features;
 
-use proc_macro2::Delimiter::*;
-use proc_macro2::*;
-use syn::{AttrStyle, Attribute, Lit};
+#[macro_use]
+mod macros;
 
-fn alone(c: char) -> TokenTree {
-    Punct::new(c, Spacing::Alone).into()
-}
-
-fn joint(c: char) -> TokenTree {
-    Punct::new(c, Spacing::Joint).into()
-}
-
-fn delimited(delim: Delimiter, tokens: Vec<TokenTree>) -> TokenTree {
-    Group::new(delim, tokens.into_iter().collect()).into()
-}
-
-fn word(sym: &str) -> TokenTree {
-    Ident::new(sym, Span::call_site()).into()
-}
+use proc_macro2::TokenStream;
+use quote::quote;
+use syn::Lit;
 
 #[test]
 fn test_struct() {
-    let raw = "
+    let code = "
         #[derive(Debug, Clone)]
         pub struct Item {
             pub ident: Ident,
@@ -35,58 +21,12 @@
         }
     ";
 
-    let expected = vec![
-        alone('#'),
-        delimited(
-            Bracket,
-            vec![
-                word("derive"),
-                delimited(Parenthesis, vec![word("Debug"), alone(','), word("Clone")]),
-            ],
-        ),
-        word("pub"),
-        word("struct"),
-        word("Item"),
-        delimited(
-            Brace,
-            vec![
-                word("pub"),
-                word("ident"),
-                alone(':'),
-                word("Ident"),
-                alone(','),
-                word("pub"),
-                word("attrs"),
-                alone(':'),
-                word("Vec"),
-                alone('<'),
-                word("Attribute"),
-                joint('>'),
-                alone(','),
-            ],
-        ),
-    ];
-
-    fn wrap(tts: TokenStream) -> Attribute {
-        Attribute {
-            style: AttrStyle::Outer,
-            pound_token: Default::default(),
-            bracket_token: Default::default(),
-            path: Ident::new("test", Span::call_site()).into(),
-            tts,
-        }
-    }
-
-    let result = wrap(raw.parse().unwrap());
-    let expected = wrap(expected.into_iter().collect());
-    if result != expected {
-        panic!("{:#?}\n!=\n{:#?}", result.tts, expected.tts);
-    }
+    snapshot!(code as TokenStream);
 }
 
 #[test]
 fn test_literal_mangling() {
-    let raw = "0_4";
-    let parsed: Lit = syn::parse_str(raw).unwrap();
-    assert_eq!(raw, quote!(#parsed).to_string());
+    let code = "0_4";
+    let parsed: Lit = syn::parse_str(code).unwrap();
+    assert_eq!(code, quote!(#parsed).to_string());
 }