diff --git a/generator/Data/XCB/Python/Parse.hs b/generator/Data/XCB/Python/Parse.hs
--- a/generator/Data/XCB/Python/Parse.hs
+++ b/generator/Data/XCB/Python/Parse.hs
@@ -325,7 +325,7 @@
                    -> TypeInfoMap
                    -> (String -> String)
                    -> GenStructElem Type
-                   -> Either (Maybe String, String) [(String, Expr ())]
+                   -> Either (Maybe String, String) [(String, Maybe (Expr ()))]
 structElemToPyPack _ _ _ (Pad i) = Left (Nothing, mkPad i)
 -- TODO: implement doc, switch, and fd?
 structElemToPyPack _ _ _ (Doc _ _ _) = Left (Nothing, "")
@@ -340,34 +340,34 @@
              trueB = mkCall (name ++ ".pack") noArgs
              synthetic = mkCall (typNam ++ ".synthetic") [mkArg ("*" ++ name)]
              falseB = mkCall (mkDot synthetic "pack") noArgs
-         in Right $ [(name, CondExpr trueB cond falseB ())]
+         in Right $ [(name, Just (CondExpr trueB cond falseB ()))]
 -- TODO: assert values are in enum?
 structElemToPyPack ext m accessor (X.List n typ expr _) =
   let name = accessor n
       -- The convention seems to be either to have a <fieldref> nested in the
-      -- list, or use "%s_len" % name if there is no fieldref. We use a little
-      -- hack here and write an empty string, since we don't need to write this
-      -- length, but we have no way to indicate that right now.
-      list_len = if isNothing expr then [(name ++ "_len", mkStr "")] else []
+      -- list, or use "%s_len" % name if there is no fieldref. We need to add
+      -- the _len to the arguments of the function but we don't need to pack
+      -- anything, which we denote using Nothing
+      list_len = if isNothing expr then [(name ++ "_len", Nothing)] else []
       list = case m M.! typ of
-        BaseType c -> [(name, mkCall "xcffib.pack_list" [ mkName $ name
+        BaseType c -> [(name, Just (mkCall "xcffib.pack_list" [ mkName $ name
                                                         , mkStr c
-                                                        ])]
+                                                        ]))]
         CompositeType tExt c ->
           let c' = if tExt == ext then c else (tExt ++ "." ++ c)
-          in [(name, mkCall "xcffib.pack_list" ([ mkName $ name
+          in [(name, Just (mkCall "xcffib.pack_list" ([ mkName $ name
                                                 , mkName c'
-                                                ]))]
+                                                ])))]
   in Right $ list_len ++ list
 structElemToPyPack _ m accessor (ExprField name typ expr) =
   let e = (xExpressionToPyExpr accessor) expr
       name' = accessor name
   in case m M.! typ of
-       BaseType c -> Right $ [(name', mkCall "struct.pack" [ mkStr ('=' : c)
+       BaseType c -> Right $ [(name', Just (mkCall "struct.pack" [ mkStr ('=' : c)
                                                            , e
-                                                           ])]
+                                                           ]))]
        CompositeType _ _ -> Right $ [(name',
-                                      mkCall (mkDot e "pack") noArgs)]
+                                      Just (mkCall (mkDot e "pack") noArgs))]
 
 -- As near as I can tell here the padding param is unused.
 structElemToPyPack _ m accessor (ValueParam typ mask _ list) =
@@ -377,7 +377,7 @@
           list' = mkCall "xcffib.pack_list" [ mkName $ accessor list
                                             , mkStr "I"
                                             ]
-      in Right $ [(mask, mask'), (list, list')]
+      in Right $ [(mask, Just mask'), (list, Just list')]
     CompositeType _ _ -> error (
       "ValueParams other than CARD{16,32} not allowed.")
 
@@ -394,7 +394,7 @@
 mkPackStmts ext name m accessor prefix membs =
   let packF = structElemToPyPack ext m accessor
       (toPack, stmts) = partitionEithers $ map packF membs
-      listWrites = map (flip StmtExpr () . mkCall "buf.write" . (: [])) lists
+      listWrites = map (flip StmtExpr () . mkCall "buf.write" . (: [])) $ catMaybes lists
       (args, keys) = let (as, ks) = unzip toPack in (catMaybes as, ks)
 
       -- In some cases (e.g. xproto.ConfigureWindow) there is padding after
diff --git a/test/GeneratorTests.hs b/test/GeneratorTests.hs
new file mode 100644
--- /dev/null
+++ b/test/GeneratorTests.hs
@@ -0,0 +1,73 @@
+{-
+ - Copyright 2014 Tycho Andersen
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ -   http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -}
+module Main (main) where
+
+import Language.Python.Common
+
+import Data.XCB.Python.Parse
+import Data.XCB.FromXML
+import Data.XCB.Types
+
+import Test.Framework ( defaultMain, Test )
+import Test.Framework.Providers.HUnit
+import Test.HUnit hiding ( Test )
+
+import System.FilePath
+
+pyTests :: [String]
+pyTests = [ "event"
+          , "error"
+          , "request"
+          , "union"
+          , "struct"
+          , "enum"
+          , "request_reply"
+          , "no_sequence"
+          , "type_pad"
+          , "render_1.7"
+          , "xproto_1.7"
+          , "render"
+          ]
+
+mkFname :: String -> FilePath
+mkFname = (</>) $ "test" </> "generator"
+
+mkTest :: String -> IO Test
+mkTest name = do
+  header <- fromFiles [mkFname $ name <.> ".xml"]
+  rawExpected <- readFile . mkFname $ name <.> ".py"
+  let [(fname, outPy)] = xform header
+      rawOut = renderPy outPy
+  return $ testCase name $ do assertEqual "names equal" name fname
+                              -- TODO: we should really parse and compare ASTs
+                              assertEqual "rendering equal" rawExpected rawOut
+
+
+calcsizeTests :: [Test]
+calcsizeTests =
+  let tests = [ ("x2xBx", 5)
+              , ("24xHhII", 24 + 2 * 2 + 2 * 4)
+              ]
+  in map mkTest tests
+  where
+    mkTest (str, expected) =
+      let result = calcsize str
+      in testCase "calcsize" (assertEqual str expected result)
+
+main :: IO ()
+main = do
+  genTests <- mapM mkTest pyTests
+  defaultMain $ calcsizeTests ++ genTests
diff --git a/test/PyHelpersTests.hs b/test/PyHelpersTests.hs
new file mode 100644
--- /dev/null
+++ b/test/PyHelpersTests.hs
@@ -0,0 +1,45 @@
+{-
+ - Copyright 2014 Tycho Andersen
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ -   http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -}
+module Main (main) where
+
+import Language.Python.Common
+
+import Data.XCB.Python.PyHelpers
+
+import Test.Framework ( defaultMain, Test )
+import Test.Framework.Providers.HUnit
+import Test.HUnit hiding ( Test )
+
+mkTest :: (Show a, Eq a) => String -> a -> a -> Test
+mkTest name t1 t2 = testCase name (assertEqual name t1 t2)
+
+testMkName :: Test
+testMkName =
+  let result = mkName "self.foo.bar"
+      expected = (Dot (Dot (Var (Ident "self" ()) ())
+                           (Ident "foo" ()) ())
+                      (Ident "bar" ()) ())
+  in mkTest "testMkName" expected result
+
+testReserves :: Test
+testReserves =
+  let result = mkName "None"
+      expected = (Var (Ident "_None" ()) ())
+  in mkTest "testReserves" expected result
+
+main :: IO ()
+main = do
+  defaultMain [testMkName, testReserves]
diff --git a/test/generator/enum.py b/test/generator/enum.py
new file mode 100644
--- /dev/null
+++ b/test/generator/enum.py
@@ -0,0 +1,39 @@
+import xcffib
+import struct
+import six
+_events = {}
+_errors = {}
+class DeviceUse:
+    IsXPointer = 0
+    IsXKeyboard = 1
+    IsXExtensionDevice = 2
+    IsXExtensionKeyboard = 3
+    IsXExtensionPointer = 4
+class EventMask:
+    NoEvent = 0
+    KeyPress = 1 << 0
+    KeyRelease = 1 << 1
+    ButtonPress = 1 << 2
+    ButtonRelease = 1 << 3
+    EnterWindow = 1 << 4
+    LeaveWindow = 1 << 5
+    PointerMotion = 1 << 6
+    PointerMotionHint = 1 << 7
+    Button1Motion = 1 << 8
+    Button2Motion = 1 << 9
+    Button3Motion = 1 << 10
+    Button4Motion = 1 << 11
+    Button5Motion = 1 << 12
+    ButtonMotion = 1 << 13
+    KeymapState = 1 << 14
+    Exposure = 1 << 15
+    VisibilityChange = 1 << 16
+    StructureNotify = 1 << 17
+    ResizeRedirect = 1 << 18
+    SubstructureNotify = 1 << 19
+    SubstructureRedirect = 1 << 20
+    FocusChange = 1 << 21
+    PropertyChange = 1 << 22
+    ColorMapChange = 1 << 23
+    OwnerGrabButton = 1 << 24
+xcffib._add_ext(key, enumExtension, _events, _errors)
diff --git a/test/generator/enum.xml b/test/generator/enum.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/enum.xml
@@ -0,0 +1,41 @@
+<!-- based on xproto -->
+<xcb header="enum">
+
+    <enum name="DeviceUse">
+        <item name="IsXPointer">           <value>0</value> </item>
+        <item name="IsXKeyboard">          <value>1</value> </item>
+        <item name="IsXExtensionDevice">   <value>2</value> </item>
+        <item name="IsXExtensionKeyboard"> <value>3</value> </item>
+        <item name="IsXExtensionPointer">  <value>4</value> </item>
+    </enum>
+
+  <enum name="EventMask">
+    <item name="NoEvent">           <value>0</value></item>
+    <item name="KeyPress">            <bit>0</bit></item>
+    <item name="KeyRelease">          <bit>1</bit></item>
+    <item name="ButtonPress">         <bit>2</bit></item>
+    <item name="ButtonRelease">       <bit>3</bit></item>
+    <item name="EnterWindow">         <bit>4</bit></item>
+    <item name="LeaveWindow">         <bit>5</bit></item>
+    <item name="PointerMotion">       <bit>6</bit></item>
+    <item name="PointerMotionHint">   <bit>7</bit></item>
+    <item name="Button1Motion">       <bit>8</bit></item>
+    <item name="Button2Motion">       <bit>9</bit></item>
+    <item name="Button3Motion">       <bit>10</bit></item>
+    <item name="Button4Motion">       <bit>11</bit></item>
+    <item name="Button5Motion">       <bit>12</bit></item>
+    <item name="ButtonMotion">        <bit>13</bit></item>
+    <item name="KeymapState">         <bit>14</bit></item>
+    <item name="Exposure">            <bit>15</bit></item>
+    <item name="VisibilityChange">    <bit>16</bit></item>
+    <item name="StructureNotify">     <bit>17</bit></item>
+    <item name="ResizeRedirect">      <bit>18</bit></item>
+    <item name="SubstructureNotify">  <bit>19</bit></item>
+    <item name="SubstructureRedirect"><bit>20</bit></item>
+    <item name="FocusChange">         <bit>21</bit></item>
+    <item name="PropertyChange">      <bit>22</bit></item>
+    <item name="ColorMapChange">      <bit>23</bit></item>
+    <item name="OwnerGrabButton">     <bit>24</bit></item>
+  </enum>
+
+</xcb>
diff --git a/test/generator/error.py b/test/generator/error.py
new file mode 100644
--- /dev/null
+++ b/test/generator/error.py
@@ -0,0 +1,24 @@
+import xcffib
+import struct
+import six
+MAJOR_VERSION = 2
+MINOR_VERSION = 2
+key = xcffib.ExtensionKey("ERROR")
+_events = {}
+_errors = {}
+class RequestError(xcffib.Error):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Error.__init__(self, unpacker)
+        base = unpacker.offset
+        self.bad_value, self.minor_opcode, self.major_opcode = unpacker.unpack("xx2xIHBx")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=B", 1))
+        buf.write(struct.pack("=x2xIHBx", self.bad_value, self.minor_opcode, self.major_opcode))
+        return buf.getvalue()
+BadRequest = RequestError
+_errors[1] = RequestError
+xcffib._add_ext(key, errorExtension, _events, _errors)
diff --git a/test/generator/error.xml b/test/generator/error.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/error.xml
@@ -0,0 +1,11 @@
+<!-- stolen from xv -->
+<xcb header="error" extension-xname="ERROR" extension-name="Error"
+    major-version="2" minor-version="2">
+
+  <error name="Request" number="1">
+    <field type="CARD32" name="bad_value" />
+    <field type="CARD16" name="minor_opcode" />
+    <field type="CARD8" name="major_opcode" />
+    <pad bytes="1" />
+  </error>
+</xcb>
diff --git a/test/generator/event.py b/test/generator/event.py
new file mode 100644
--- /dev/null
+++ b/test/generator/event.py
@@ -0,0 +1,41 @@
+import xcffib
+import struct
+import six
+MAJOR_VERSION = 1
+MINOR_VERSION = 4
+key = xcffib.ExtensionKey("EVENT")
+_events = {}
+_errors = {}
+class ScreenChangeNotifyEvent(xcffib.Event):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Event.__init__(self, unpacker)
+        base = unpacker.offset
+        self.rotation, self.timestamp, self.config_timestamp, self.root, self.request_window, self.sizeID, self.subpixel_order, self.width, self.height, self.mwidth, self.mheight = unpacker.unpack("xB2xIIIIHHHHHH")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=B", 0))
+        buf.write(struct.pack("=B2xIIIIHHHHHH", self.rotation, self.timestamp, self.config_timestamp, self.root, self.request_window, self.sizeID, self.subpixel_order, self.width, self.height, self.mwidth, self.mheight))
+        buf_len = len(buf.getvalue())
+        if buf_len < 32:
+            buf.write(struct.pack("x" * (32 - buf_len)))
+        return buf.getvalue()
+    @classmethod
+    def synthetic(cls, rotation, timestamp, config_timestamp, root, request_window, sizeID, subpixel_order, width, height, mwidth, mheight):
+        self = cls.__new__(cls)
+        self.rotation = rotation
+        self.timestamp = timestamp
+        self.config_timestamp = config_timestamp
+        self.root = root
+        self.request_window = request_window
+        self.sizeID = sizeID
+        self.subpixel_order = subpixel_order
+        self.width = width
+        self.height = height
+        self.mwidth = mwidth
+        self.mheight = mheight
+        return self
+_events[0] = ScreenChangeNotifyEvent
+xcffib._add_ext(key, eventExtension, _events, _errors)
diff --git a/test/generator/event.xml b/test/generator/event.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/event.xml
@@ -0,0 +1,21 @@
+<!-- stolen from randr -->
+<xcb header="event" extension-xname="EVENT" extension-name="Event"
+    major-version="1" minor-version="4">
+
+  <xidtype name="WINDOW" />
+  <typedef oldname="CARD32" newname="TIMESTAMP" />
+
+  <event name="ScreenChangeNotify" number="0">
+    <field type="CARD8" name="rotation" mask="Rotation" />
+    <field type="TIMESTAMP" name="timestamp" />
+    <field type="TIMESTAMP" name="config_timestamp" />
+    <field type="WINDOW" name="root" />
+    <field type="WINDOW" name="request_window" />
+    <field type="CARD16" name="sizeID" />
+    <field type="CARD16" name="subpixel_order" enum="SubPixel" />
+    <field type="CARD16" name="width" />
+    <field type="CARD16" name="height" />
+    <field type="CARD16" name="mwidth" />
+    <field type="CARD16" name="mheight" />
+  </event>
+</xcb>
diff --git a/test/generator/no_sequence.py b/test/generator/no_sequence.py
new file mode 100644
--- /dev/null
+++ b/test/generator/no_sequence.py
@@ -0,0 +1,29 @@
+import xcffib
+import struct
+import six
+_events = {}
+_errors = {}
+class KeymapNotifyEvent(xcffib.Event):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Event.__init__(self, unpacker)
+        base = unpacker.offset
+        unpacker.unpack("x")
+        self.keys = xcffib.List(unpacker, "B", 31)
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=B", 11))
+        buf.write(xcffib.pack_list(self.keys, "B"))
+        buf_len = len(buf.getvalue())
+        if buf_len < 32:
+            buf.write(struct.pack("x" * (32 - buf_len)))
+        return buf.getvalue()
+    @classmethod
+    def synthetic(cls, keys):
+        self = cls.__new__(cls)
+        self.keys = keys
+        return self
+_events[11] = KeymapNotifyEvent
+xcffib._add_ext(key, no_sequenceExtension, _events, _errors)
diff --git a/test/generator/no_sequence.xml b/test/generator/no_sequence.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/no_sequence.xml
@@ -0,0 +1,5 @@
+<xcb header="no_sequence">
+  <event name="KeymapNotify" number="11" no-sequence-number="true">
+    <list type="CARD8" name="keys"><value>31</value></list>
+  </event>
+</xcb>
diff --git a/test/generator/render.py b/test/generator/render.py
new file mode 100644
--- /dev/null
+++ b/test/generator/render.py
@@ -0,0 +1,58 @@
+import xcffib
+import struct
+import six
+MAJOR_VERSION = 0
+MINOR_VERSION = 11
+key = xcffib.ExtensionKey("RENDER")
+_events = {}
+_errors = {}
+class COLOR(xcffib.Struct):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.red, self.green, self.blue, self.alpha = unpacker.unpack("HHHH")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=HHHH", self.red, self.green, self.blue, self.alpha))
+        return buf.getvalue()
+    fixed_size = 8
+    @classmethod
+    def synthetic(cls, red, green, blue, alpha):
+        self = cls.__new__(cls)
+        self.red = red
+        self.green = green
+        self.blue = blue
+        self.alpha = alpha
+        return self
+class RECTANGLE(xcffib.Struct):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.x, self.y, self.width, self.height = unpacker.unpack("hhHH")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=hhHH", self.x, self.y, self.width, self.height))
+        return buf.getvalue()
+    fixed_size = 8
+    @classmethod
+    def synthetic(cls, x, y, width, height):
+        self = cls.__new__(cls)
+        self.x = x
+        self.y = y
+        self.width = width
+        self.height = height
+        return self
+class renderExtension(xcffib.Extension):
+    def FillRectangles(self, op, dst, color, rects_len, rects, is_checked=False):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=xx2xB3xI", op, dst))
+        buf.write(color.pack() if hasattr(color, "pack") else COLOR.synthetic(*color).pack())
+        buf.write(xcffib.pack_list(rects, RECTANGLE))
+        return self.send_request(26, buf, is_checked=is_checked)
+xcffib._add_ext(key, renderExtension, _events, _errors)
diff --git a/test/generator/render.xml b/test/generator/render.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/render.xml
@@ -0,0 +1,27 @@
+<xcb header="render" extension-xname="RENDER" extension-name="Render"
+    major-version="0" minor-version="11">
+
+  <struct name="COLOR">
+    <field type="CARD16" name="red" />
+    <field type="CARD16" name="green" />
+    <field type="CARD16" name="blue" />
+    <field type="CARD16" name="alpha" />
+  </struct>
+
+  <xidtype name="PICTURE" />
+
+  <struct name="RECTANGLE">
+    <field type="INT16" name="x" />
+    <field type="INT16" name="y" />
+    <field type="CARD16" name="width" />
+    <field type="CARD16" name="height" />
+  </struct>
+
+  <request name="FillRectangles" opcode="26">
+    <field type="CARD8" name="op" enum="PictOp" />
+    <pad bytes="3" />
+    <field type="PICTURE" name="dst" />
+    <field type="COLOR" name="color" />
+    <list type="RECTANGLE" name="rects" />
+  </request>
+</xcb>
diff --git a/test/generator/render_1.7.py b/test/generator/render_1.7.py
new file mode 100644
--- /dev/null
+++ b/test/generator/render_1.7.py
@@ -0,0 +1,63 @@
+import xcffib
+import struct
+import six
+MAJOR_VERSION = 0
+MINOR_VERSION = 11
+key = xcffib.ExtensionKey("RENDER")
+_events = {}
+_errors = {}
+class PictOp:
+    Clear = 0
+    Src = 1
+    Dst = 2
+    Over = 3
+    OverReverse = 4
+    In = 5
+    InReverse = 6
+    Out = 7
+    OutReverse = 8
+    Atop = 9
+    AtopReverse = 10
+    Xor = 11
+    Add = 12
+    Saturate = 13
+    DisjointClear = 16
+    DisjointSrc = 17
+    DisjointDst = 18
+    DisjointOver = 19
+    DisjointOverReverse = 20
+    DisjointIn = 21
+    DisjointInReverse = 22
+    DisjointOut = 23
+    DisjointOutReverse = 24
+    DisjointAtop = 25
+    DisjointAtopReverse = 26
+    DisjointXor = 27
+    ConjointClear = 32
+    ConjointSrc = 33
+    ConjointDst = 34
+    ConjointOver = 35
+    ConjointOverReverse = 36
+    ConjointIn = 37
+    ConjointInReverse = 38
+    ConjointOut = 39
+    ConjointOutReverse = 40
+    ConjointAtop = 41
+    ConjointAtopReverse = 42
+    ConjointXor = 43
+    Multiply = 48
+    Screen = 49
+    Overlay = 50
+    Darken = 51
+    Lighten = 52
+    ColorDodge = 53
+    ColorBurn = 54
+    HardLight = 55
+    SoftLight = 56
+    Difference = 57
+    Exclusion = 58
+    HSLHue = 59
+    HSLSaturation = 60
+    HSLColor = 61
+    HSLLuminosity = 62
+xcffib._add_ext(key, render_1._7Extension, _events, _errors)
diff --git a/test/generator/render_1.7.xml b/test/generator/render_1.7.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/render_1.7.xml
@@ -0,0 +1,69 @@
+<!-- rendering of this enum in xcb-proto 1.7 is vastly more complicated than in
+     more modern versions of xcb-proto, but for completness we should render
+     this correctly as well -->
+<?xml version="1.0" encoding="utf-8"?>
+<xcb header="render_1.7" extension-xname="RENDER" extension-name="Render"
+    major-version="0" minor-version="11">
+
+  <!-- Disjoint* and Conjoint* are new in version 0.2 -->
+  <!-- PDF blend modes are new in version 0.11 -->
+  <enum name="PictOp">
+    <item name="Clear" />
+    <item name="Src" />
+    <item name="Dst" />
+    <item name="Over" />
+    <item name="OverReverse" />
+    <item name="In" />
+    <item name="InReverse" />
+    <item name="Out" />
+    <item name="OutReverse" />
+    <item name="Atop" />
+    <item name="AtopReverse" />
+    <item name="Xor" />
+    <item name="Add" />
+    <item name="Saturate" />
+    
+    <item name="DisjointClear"><value>16</value></item>
+    <item name="DisjointSrc" />
+    <item name="DisjointDst" />
+    <item name="DisjointOver" />
+    <item name="DisjointOverReverse" />
+    <item name="DisjointIn" />
+    <item name="DisjointInReverse" />
+    <item name="DisjointOut" />
+    <item name="DisjointOutReverse" />
+    <item name="DisjointAtop" />
+    <item name="DisjointAtopReverse" />
+    <item name="DisjointXor" />
+    
+    <item name="ConjointClear"><value>32</value></item>
+    <item name="ConjointSrc" />
+    <item name="ConjointDst" />
+    <item name="ConjointOver" />
+    <item name="ConjointOverReverse" />
+    <item name="ConjointIn" />
+    <item name="ConjointInReverse" />
+    <item name="ConjointOut" />
+    <item name="ConjointOutReverse" />
+    <item name="ConjointAtop" />
+    <item name="ConjointAtopReverse" />
+    <item name="ConjointXor" />
+
+    <!-- PDF blend modes are new in version 0.11 -->
+    <item name="Multiply"><value>48</value></item>
+    <item name="Screen" />
+    <item name="Overlay" />
+    <item name="Darken" />
+    <item name="Lighten" />
+    <item name="ColorDodge" />
+    <item name="ColorBurn" />
+    <item name="HardLight" />
+    <item name="SoftLight" />
+    <item name="Difference" />
+    <item name="Exclusion" />
+    <item name="HSLHue" />
+    <item name="HSLSaturation" />
+    <item name="HSLColor" />
+    <item name="HSLLuminosity" />
+  </enum>
+</xcb>
diff --git a/test/generator/request.py b/test/generator/request.py
new file mode 100644
--- /dev/null
+++ b/test/generator/request.py
@@ -0,0 +1,13 @@
+import xcffib
+import struct
+import six
+_events = {}
+_errors = {}
+class requestExtension(xcffib.Extension):
+    def CreateWindow(self, depth, wid, parent, x, y, width, height, border_width, _class, visual, value_mask, value_list, is_checked=False):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=xx2xBIIhhHHHHI", depth, wid, parent, x, y, width, height, border_width, _class, visual))
+        buf.write(struct.pack("=I", value_mask))
+        buf.write(xcffib.pack_list(value_list, "I"))
+        return self.send_request(1, buf, is_checked=is_checked)
+xcffib._add_ext(key, requestExtension, _events, _errors)
diff --git a/test/generator/request.xml b/test/generator/request.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/request.xml
@@ -0,0 +1,90 @@
+<!-- based on xproto -->
+<xcb header="request">
+
+  <xidtype name="WINDOW" />
+  <typedef oldname="CARD32" newname="TIMESTAMP" />
+  <typedef oldname="CARD32" newname="VISUALID" />
+
+  <request name="CreateWindow" opcode="1">
+    <field type="CARD8" name="depth" />
+    <field type="WINDOW" name="wid" />
+    <field type="WINDOW" name="parent" />
+    <field type="INT16" name="x" />
+    <field type="INT16" name="y" />
+    <field type="CARD16" name="width" />
+    <field type="CARD16" name="height" />
+    <field type="CARD16" name="border_width" />
+    <field type="CARD16" name="class" enum="WindowClass" />
+    <field type="VISUALID" name="visual" />
+    <valueparam value-mask-type="CARD32"
+                value-mask-name="value_mask"
+                value-list-name="value_list" />
+    <doc>
+      <brief>Creates a window</brief>
+      <description><![CDATA[
+Creates an unmapped window as child of the specified `parent` window. A
+CreateNotify event will be generated. The new window is placed on top in the
+stacking order with respect to siblings.
+
+The coordinate system has the X axis horizontal and the Y axis vertical with
+the origin [0, 0] at the upper-left corner. Coordinates are integral, in terms
+of pixels, and coincide with pixel centers. Each window and pixmap has its own
+coordinate system. For a window, the origin is inside the border at the inside,
+upper-left corner.
+
+The created window is not yet displayed (mapped), call `xcb_map_window` to
+display it.
+
+The created window will initially use the same cursor as its parent.
+      ]]></description>
+      <field name="wid"><![CDATA[
+The ID with which you will refer to the new window, created by
+`xcb_generate_id`.
+      ]]></field>
+      <field name="depth"><![CDATA[
+Specifies the new window's depth.
+
+The special value `XCB_COPY_FROM_PARENT` means the depth is taken from the
+`parent` window.
+      ]]></field>
+      <field name="visual"><![CDATA[
+Specifies the id for the new window's visual.
+
+The special value `XCB_COPY_FROM_PARENT` means the visual is taken from the
+`parent` window.
+      ]]></field>
+      <field name="class"></field>
+      <field name="parent"><![CDATA[
+The parent window of the new window.
+      ]]></field>
+      <field name="border_width"><![CDATA[
+
+Must be zero if the `class` is `InputOnly` or a `xcb_match_error_t` occurs.
+      ]]></field>
+      <field name="x"><![CDATA[The X coordinate of the new window.]]></field>
+      <field name="y"><![CDATA[The Y coordinate of the new window.]]></field>
+      <field name="width"><![CDATA[The width of the new window.]]></field>
+      <field name="height"><![CDATA[The height of the new window.]]></field>
+      <error type="Colormap"><![CDATA[
+      ]]></error>
+      <error type="Match"><![CDATA[
+      ]]></error>
+      <error type="Cursor"><![CDATA[
+      ]]></error>
+      <error type="Pixmap"><![CDATA[
+      ]]></error>
+      <error type="Value"><![CDATA[
+      ]]></error>
+      <error type="Window"><![CDATA[
+      ]]></error>
+      <error type="Alloc"><![CDATA[
+The X server could not allocate the requested resources (no memory?).
+      ]]></error>
+      <see type="function" name="xcb_generate_id" />
+      <see type="request" name="MapWindow" />
+      <see type="event" name="CreateNotify" />
+    </doc>
+
+  </request>
+
+</xcb>
diff --git a/test/generator/request_reply.py b/test/generator/request_reply.py
new file mode 100644
--- /dev/null
+++ b/test/generator/request_reply.py
@@ -0,0 +1,42 @@
+import xcffib
+import struct
+import six
+_events = {}
+_errors = {}
+class STR(xcffib.Struct):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.name_len, = unpacker.unpack("B")
+        self.name = xcffib.List(unpacker, "c", self.name_len)
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=B", self.name_len))
+        buf.write(xcffib.pack_list(self.name, "c"))
+        return buf.getvalue()
+    @classmethod
+    def synthetic(cls, name_len, name):
+        self = cls.__new__(cls)
+        self.name_len = name_len
+        self.name = name
+        return self
+class ListExtensionsReply(xcffib.Reply):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Reply.__init__(self, unpacker)
+        base = unpacker.offset
+        self.names_len, = unpacker.unpack("xB2x4x24x")
+        self.names = xcffib.List(unpacker, STR, self.names_len)
+        self.bufsize = unpacker.offset - base
+class ListExtensionsCookie(xcffib.Cookie):
+    reply_type = ListExtensionsReply
+class request_replyExtension(xcffib.Extension):
+    def ListExtensions(self, is_checked=True):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=xx2x"))
+        return self.send_request(99, buf, ListExtensionsCookie, is_checked=is_checked)
+xcffib._add_ext(key, request_replyExtension, _events, _errors)
diff --git a/test/generator/request_reply.xml b/test/generator/request_reply.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/request_reply.xml
@@ -0,0 +1,21 @@
+<!-- based on xproto -->
+<xcb header="request_reply">
+
+  <struct name="STR">
+    <field type="CARD8" name="name_len" />
+    <list type="char" name="name">
+      <fieldref>name_len</fieldref>
+    </list>
+  </struct>
+
+  <request name="ListExtensions" opcode="99">
+    <reply>
+      <field type="CARD8" name="names_len" />
+      <pad bytes="24" />
+      <list type="STR" name="names">
+        <fieldref>names_len</fieldref>
+      </list>
+    </reply>
+  </request>
+
+</xcb>
diff --git a/test/generator/struct.py b/test/generator/struct.py
new file mode 100644
--- /dev/null
+++ b/test/generator/struct.py
@@ -0,0 +1,50 @@
+import xcffib
+import struct
+import six
+_events = {}
+_errors = {}
+class AxisInfo(xcffib.Struct):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.resolution, self.minimum, self.maximum = unpacker.unpack("Iii")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=Iii", self.resolution, self.minimum, self.maximum))
+        return buf.getvalue()
+    fixed_size = 12
+    @classmethod
+    def synthetic(cls, resolution, minimum, maximum):
+        self = cls.__new__(cls)
+        self.resolution = resolution
+        self.minimum = minimum
+        self.maximum = maximum
+        return self
+class ValuatorInfo(xcffib.Struct):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.class_id, self.len, self.axes_len, self.mode, self.motion_size = unpacker.unpack("BBBBI")
+        self.axes = xcffib.List(unpacker, AxisInfo, self.axes_len)
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=BBBBI", self.class_id, self.len, self.axes_len, self.mode, self.motion_size))
+        buf.write(xcffib.pack_list(self.axes, AxisInfo))
+        return buf.getvalue()
+    @classmethod
+    def synthetic(cls, class_id, len, axes_len, mode, motion_size, axes):
+        self = cls.__new__(cls)
+        self.class_id = class_id
+        self.len = len
+        self.axes_len = axes_len
+        self.mode = mode
+        self.motion_size = motion_size
+        self.axes = axes
+        return self
+xcffib._add_ext(key, structExtension, _events, _errors)
diff --git a/test/generator/struct.xml b/test/generator/struct.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/struct.xml
@@ -0,0 +1,21 @@
+<!-- based on xproto -->
+<xcb header="struct">
+
+    <struct name="AxisInfo">
+        <field type="CARD32" name="resolution" />
+        <field type="INT32"  name="minimum" />
+        <field type="INT32"  name="maximum" />
+    </struct>
+
+    <struct name="ValuatorInfo">
+        <field type="CARD8"   name="class_id" enum="InputClass" />
+        <field type="CARD8"   name="len" />
+        <field type="CARD8"   name="axes_len" />
+        <field type="CARD8"   name="mode" enum="ValuatorMode" />
+        <field type="CARD32"  name="motion_size" />
+        <list type="AxisInfo" name="axes">
+            <fieldref>axes_len</fieldref>
+        </list>
+    </struct>
+
+</xcb>
diff --git a/test/generator/type_pad.py b/test/generator/type_pad.py
new file mode 100644
--- /dev/null
+++ b/test/generator/type_pad.py
@@ -0,0 +1,73 @@
+import xcffib
+import struct
+import six
+_events = {}
+_errors = {}
+class CHARINFO(xcffib.Struct):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.left_side_bearing, self.right_side_bearing, self.character_width, self.ascent, self.descent, self.attributes = unpacker.unpack("hhhhhH")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=hhhhhH", self.left_side_bearing, self.right_side_bearing, self.character_width, self.ascent, self.descent, self.attributes))
+        return buf.getvalue()
+    fixed_size = 12
+    @classmethod
+    def synthetic(cls, left_side_bearing, right_side_bearing, character_width, ascent, descent, attributes):
+        self = cls.__new__(cls)
+        self.left_side_bearing = left_side_bearing
+        self.right_side_bearing = right_side_bearing
+        self.character_width = character_width
+        self.ascent = ascent
+        self.descent = descent
+        self.attributes = attributes
+        return self
+class FONTPROP(xcffib.Struct):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.name, self.value = unpacker.unpack("II")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=II", self.name, self.value))
+        return buf.getvalue()
+    fixed_size = 8
+    @classmethod
+    def synthetic(cls, name, value):
+        self = cls.__new__(cls)
+        self.name = name
+        self.value = value
+        return self
+class ListFontsWithInfoReply(xcffib.Reply):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Reply.__init__(self, unpacker)
+        base = unpacker.offset
+        self.name_len, = unpacker.unpack("xB2x4x")
+        self.min_bounds = CHARINFO(unpacker)
+        unpacker.unpack("4x")
+        unpacker.pad(CHARINFO)
+        self.max_bounds = CHARINFO(unpacker)
+        self.min_char_or_byte2, self.max_char_or_byte2, self.default_char, self.properties_len, self.draw_direction, self.min_byte1, self.max_byte1, self.all_chars_exist, self.font_ascent, self.font_descent, self.replies_hint = unpacker.unpack("4xHHHHBBBBhhI")
+        unpacker.pad(FONTPROP)
+        self.properties = xcffib.List(unpacker, FONTPROP, self.properties_len)
+        unpacker.pad("c")
+        self.name = xcffib.List(unpacker, "c", self.name_len)
+        self.bufsize = unpacker.offset - base
+class ListFontsWithInfoCookie(xcffib.Cookie):
+    reply_type = ListFontsWithInfoReply
+class type_padExtension(xcffib.Extension):
+    def ListFontsWithInfo(self, max_names, pattern_len, pattern, is_checked=True):
+        buf = six.BytesIO()
+        buf.write(struct.pack("=xx2xxHH", max_names, pattern_len))
+        buf.write(xcffib.pack_list(pattern, "c"))
+        return self.send_request(50, buf, ListFontsWithInfoCookie, is_checked=is_checked)
+xcffib._add_ext(key, type_padExtension, _events, _errors)
diff --git a/test/generator/type_pad.xml b/test/generator/type_pad.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/type_pad.xml
@@ -0,0 +1,111 @@
+<xcb header="type_pad">
+
+  <struct name="CHARINFO">
+    <field type="INT16" name="left_side_bearing" />
+    <field type="INT16" name="right_side_bearing" />
+    <field type="INT16" name="character_width" />
+    <field type="INT16" name="ascent" />
+    <field type="INT16" name="descent" />
+    <field type="CARD16" name="attributes" />
+  </struct>
+
+  <xidtype name="ATOM" />
+
+  <struct name="FONTPROP">
+    <field type="ATOM" name="name" />
+    <field type="CARD32" name="value" />
+  </struct>
+
+  <request name="ListFontsWithInfo" opcode="50">
+    <pad bytes="1" />
+    <field type="CARD16" name="max_names" />
+    <field type="CARD16" name="pattern_len" />
+    <list type="char" name="pattern">
+      <fieldref>pattern_len</fieldref>
+    </list>
+    <reply>
+      <field type="CARD8" name="name_len" />
+      <field type="CHARINFO" name="min_bounds" />
+      <pad bytes="4" />
+      <field type="CHARINFO" name="max_bounds" />
+      <pad bytes="4" />
+      <field type="CARD16" name="min_char_or_byte2" />
+      <field type="CARD16" name="max_char_or_byte2" />
+      <field type="CARD16" name="default_char" />
+      <field type="CARD16" name="properties_len" />
+      <field type="BYTE" name="draw_direction" enum="FontDraw" />
+      <field type="CARD8" name="min_byte1" />
+      <field type="CARD8" name="max_byte1" />
+      <field type="BOOL" name="all_chars_exist" />
+      <field type="INT16" name="font_ascent" />
+      <field type="INT16" name="font_descent" />
+      <field type="CARD32" name="replies_hint" />
+      <list type="FONTPROP" name="properties">
+        <fieldref>properties_len</fieldref>
+      </list>
+      <list type="char" name="name">
+        <fieldref>name_len</fieldref>
+      </list>
+      <doc>
+        <field name="name_len"><![CDATA[
+The number of matched font names.
+        ]]></field>
+        <field name="min_bounds"><![CDATA[
+minimum bounds over all existing char
+        ]]></field>
+        <field name="max_bounds"><![CDATA[
+maximum bounds over all existing char
+        ]]></field>
+        <field name="min_char_or_byte2"><![CDATA[
+first character
+        ]]></field>
+        <field name="max_char_or_byte2"><![CDATA[
+last character
+        ]]></field>
+        <field name="default_char"><![CDATA[
+char to print for undefined character
+        ]]></field>
+        <field name="properties_len"><![CDATA[
+how many properties there are
+        ]]></field>
+        <field name="all_chars_exist"><![CDATA[
+flag if all characters have nonzero size
+        ]]></field>
+        <field name="font_ascent"><![CDATA[
+baseline to top edge of raster
+        ]]></field>
+        <field name="font_descent"><![CDATA[
+baseline to bottom edge of raster
+        ]]></field>
+        <field name="replies_hint"><![CDATA[
+An indication of how many more fonts will be returned. This is only a hint and
+may be larger or smaller than the number of fonts actually returned. A zero
+value does not guarantee that no more fonts will be returned.
+        ]]></field>
+        <!-- enum doc is sufficient -->
+        <field name="draw_direction" />
+      </doc>
+    </reply>
+    <doc>
+      <brief>get matching font names and information</brief>
+      <description><![CDATA[
+Gets a list of available font names which match the given `pattern`.
+      ]]></description>
+      <field name="pattern_len"><![CDATA[
+The length (in bytes) of `pattern`.
+      ]]></field>
+      <field name="pattern"><![CDATA[
+A font pattern, for example "-misc-fixed-*".
+
+The asterisk (*) is a wildcard for any number of characters. The question mark
+(?) is a wildcard for a single character. Use of uppercase or lowercase does
+not matter.
+      ]]></field>
+      <field name="max_names"><![CDATA[
+The maximum number of fonts to be returned.
+      ]]></field>
+    </doc>
+
+  </request>
+
+</xcb>
diff --git a/test/generator/union.py b/test/generator/union.py
new file mode 100644
--- /dev/null
+++ b/test/generator/union.py
@@ -0,0 +1,18 @@
+import xcffib
+import struct
+import six
+_events = {}
+_errors = {}
+class ClientMessageData(xcffib.Union):
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Union.__init__(self, unpacker)
+        self.data8 = xcffib.List(unpacker.copy(), "B", 20)
+        self.data16 = xcffib.List(unpacker.copy(), "H", 10)
+        self.data32 = xcffib.List(unpacker.copy(), "I", 5)
+    def pack(self):
+        buf = six.BytesIO()
+        buf.write(xcffib.pack_list(self.data8, "B"))
+        return buf.getvalue()
+xcffib._add_ext(key, unionExtension, _events, _errors)
diff --git a/test/generator/union.xml b/test/generator/union.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/union.xml
@@ -0,0 +1,12 @@
+<!-- based on xproto -->
+<xcb header="union">
+
+  <union name="ClientMessageData">
+    <!-- The format member of the ClientMessage event determines which array
+         to use. -->
+    <list type="CARD8"  name="data8" ><value>20</value></list> <!--  8 -->
+    <list type="CARD16" name="data16"><value>10</value></list> <!-- 16 -->
+    <list type="CARD32" name="data32"><value>5</value></list>  <!-- 32 -->
+  </union>
+
+</xcb>
diff --git a/test/generator/xproto_1.7.py b/test/generator/xproto_1.7.py
new file mode 100644
--- /dev/null
+++ b/test/generator/xproto_1.7.py
@@ -0,0 +1,80 @@
+import xcffib
+import struct
+import six
+MAJOR_VERSION = 0
+MINOR_VERSION = 11
+key = xcffib.ExtensionKey("XPROTO")
+_events = {}
+_errors = {}
+class Atom:
+    _None = 0
+    Any = 0
+    PRIMARY = 1
+    SECONDARY = 2
+    ARC = 3
+    ATOM = 4
+    BITMAP = 5
+    CARDINAL = 6
+    COLORMAP = 7
+    CURSOR = 8
+    CUT_BUFFER0 = 9
+    CUT_BUFFER1 = 10
+    CUT_BUFFER2 = 11
+    CUT_BUFFER3 = 12
+    CUT_BUFFER4 = 13
+    CUT_BUFFER5 = 14
+    CUT_BUFFER6 = 15
+    CUT_BUFFER7 = 16
+    DRAWABLE = 17
+    FONT = 18
+    INTEGER = 19
+    PIXMAP = 20
+    POINT = 21
+    RECTANGLE = 22
+    RESOURCE_MANAGER = 23
+    RGB_COLOR_MAP = 24
+    RGB_BEST_MAP = 25
+    RGB_BLUE_MAP = 26
+    RGB_DEFAULT_MAP = 27
+    RGB_GRAY_MAP = 28
+    RGB_GREEN_MAP = 29
+    RGB_RED_MAP = 30
+    STRING = 31
+    VISUALID = 32
+    WINDOW = 33
+    WM_COMMAND = 34
+    WM_HINTS = 35
+    WM_CLIENT_MACHINE = 36
+    WM_ICON_NAME = 37
+    WM_ICON_SIZE = 38
+    WM_NAME = 39
+    WM_NORMAL_HINTS = 40
+    WM_SIZE_HINTS = 41
+    WM_ZOOM_HINTS = 42
+    MIN_SPACE = 43
+    NORM_SPACE = 44
+    MAX_SPACE = 45
+    END_SPACE = 46
+    SUPERSCRIPT_X = 47
+    SUPERSCRIPT_Y = 48
+    SUBSCRIPT_X = 49
+    SUBSCRIPT_Y = 50
+    UNDERLINE_POSITION = 51
+    UNDERLINE_THICKNESS = 52
+    STRIKEOUT_ASCENT = 53
+    STRIKEOUT_DESCENT = 54
+    ITALIC_ANGLE = 55
+    X_HEIGHT = 56
+    QUAD_WIDTH = 57
+    WEIGHT = 58
+    POINT_SIZE = 59
+    RESOLUTION = 60
+    COPYRIGHT = 61
+    NOTICE = 62
+    FONT_NAME = 63
+    FAMILY_NAME = 64
+    FULL_NAME = 65
+    CAP_HEIGHT = 66
+    WM_CLASS = 67
+    WM_TRANSIENT_FOR = 68
+xcffib._add_ext(key, xproto_1._7Extension, _events, _errors)
diff --git a/test/generator/xproto_1.7.xml b/test/generator/xproto_1.7.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/xproto_1.7.xml
@@ -0,0 +1,81 @@
+<!-- rendering of this enum in xcb-proto 1.7 is vastly more complicated than in
+     more modern versions of xcb-proto, but for completness we should render
+     this correctly as well -->
+<?xml version="1.0" encoding="utf-8"?>
+<xcb header="xproto_1.7" extension-xname="XPROTO" extension-name="xproto"
+    major-version="0" minor-version="11">
+
+  <enum name="Atom">
+    <item name="None"> <value>0</value></item>
+    <item name="Any">  <value>0</value></item>
+    <item name="PRIMARY" />
+    <item name="SECONDARY" />
+    <item name="ARC" />
+    <item name="ATOM" />
+    <item name="BITMAP" />
+    <item name="CARDINAL" />
+    <item name="COLORMAP" />
+    <item name="CURSOR" />
+    <item name="CUT_BUFFER0" />
+    <item name="CUT_BUFFER1" />
+    <item name="CUT_BUFFER2" />
+    <item name="CUT_BUFFER3" />
+    <item name="CUT_BUFFER4" />
+    <item name="CUT_BUFFER5" />
+    <item name="CUT_BUFFER6" />
+    <item name="CUT_BUFFER7" />
+    <item name="DRAWABLE" />
+    <item name="FONT" />
+    <item name="INTEGER" />
+    <item name="PIXMAP" />
+    <item name="POINT" />
+    <item name="RECTANGLE" />
+    <item name="RESOURCE_MANAGER" />
+    <item name="RGB_COLOR_MAP" />
+    <item name="RGB_BEST_MAP" />
+    <item name="RGB_BLUE_MAP" />
+    <item name="RGB_DEFAULT_MAP" />
+    <item name="RGB_GRAY_MAP" />
+    <item name="RGB_GREEN_MAP" />
+    <item name="RGB_RED_MAP" />
+    <item name="STRING" />
+    <item name="VISUALID" />
+    <item name="WINDOW" />
+    <item name="WM_COMMAND" />
+    <item name="WM_HINTS" />
+    <item name="WM_CLIENT_MACHINE" />
+    <item name="WM_ICON_NAME" />
+    <item name="WM_ICON_SIZE" />
+    <item name="WM_NAME" />
+    <item name="WM_NORMAL_HINTS" />
+    <item name="WM_SIZE_HINTS" />
+    <item name="WM_ZOOM_HINTS" />
+    <item name="MIN_SPACE" />
+    <item name="NORM_SPACE" />
+    <item name="MAX_SPACE" />
+    <item name="END_SPACE" />
+    <item name="SUPERSCRIPT_X" />
+    <item name="SUPERSCRIPT_Y" />
+    <item name="SUBSCRIPT_X" />
+    <item name="SUBSCRIPT_Y" />
+    <item name="UNDERLINE_POSITION" />
+    <item name="UNDERLINE_THICKNESS" />
+    <item name="STRIKEOUT_ASCENT" />
+    <item name="STRIKEOUT_DESCENT" />
+    <item name="ITALIC_ANGLE" />
+    <item name="X_HEIGHT" />
+    <item name="QUAD_WIDTH" />
+    <item name="WEIGHT" />
+    <item name="POINT_SIZE" />
+    <item name="RESOLUTION" />
+    <item name="COPYRIGHT" />
+    <item name="NOTICE" />
+    <item name="FONT_NAME" />
+    <item name="FAMILY_NAME" />
+    <item name="FULL_NAME" />
+    <item name="CAP_HEIGHT" />
+    <item name="WM_CLASS" />
+    <item name="WM_TRANSIENT_FOR" />
+  </enum>
+
+</xcb>
diff --git a/tests/GeneratorTests.hs b/tests/GeneratorTests.hs
deleted file mode 100644
--- a/tests/GeneratorTests.hs
+++ /dev/null
@@ -1,73 +0,0 @@
-{-
- - Copyright 2014 Tycho Andersen
- -
- - Licensed under the Apache License, Version 2.0 (the "License");
- - you may not use this file except in compliance with the License.
- - You may obtain a copy of the License at
- -
- -   http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing, software
- - distributed under the License is distributed on an "AS IS" BASIS,
- - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- - See the License for the specific language governing permissions and
- - limitations under the License.
- -}
-module Main (main) where
-
-import Language.Python.Common
-
-import Data.XCB.Python.Parse
-import Data.XCB.FromXML
-import Data.XCB.Types
-
-import Test.Framework ( defaultMain, Test )
-import Test.Framework.Providers.HUnit
-import Test.HUnit hiding ( Test )
-
-import System.FilePath
-
-pyTests :: [String]
-pyTests = [ "event"
-          , "error"
-          , "request"
-          , "union"
-          , "struct"
-          , "enum"
-          , "request_reply"
-          , "no_sequence"
-          , "type_pad"
-          , "render_1.7"
-          , "xproto_1.7"
-          , "render"
-          ]
-
-mkFname :: String -> FilePath
-mkFname = (</>) $ "tests" </> "generator"
-
-mkTest :: String -> IO Test
-mkTest name = do
-  header <- fromFiles [mkFname $ name <.> ".xml"]
-  rawExpected <- readFile . mkFname $ name <.> ".py"
-  let [(fname, outPy)] = xform header
-      rawOut = renderPy outPy
-  return $ testCase name $ do assertEqual "names equal" name fname
-                              -- TODO: we should really parse and compare ASTs
-                              assertEqual "rendering equal" rawExpected rawOut
-
-
-calcsizeTests :: [Test]
-calcsizeTests =
-  let tests = [ ("x2xBx", 5)
-              , ("24xHhII", 24 + 2 * 2 + 2 * 4)
-              ]
-  in map mkTest tests
-  where
-    mkTest (str, expected) =
-      let result = calcsize str
-      in testCase "calcsize" (assertEqual str expected result)
-
-main :: IO ()
-main = do
-  genTests <- mapM mkTest pyTests
-  defaultMain $ calcsizeTests ++ genTests
diff --git a/tests/PyHelpersTests.hs b/tests/PyHelpersTests.hs
deleted file mode 100644
--- a/tests/PyHelpersTests.hs
+++ /dev/null
@@ -1,45 +0,0 @@
-{-
- - Copyright 2014 Tycho Andersen
- -
- - Licensed under the Apache License, Version 2.0 (the "License");
- - you may not use this file except in compliance with the License.
- - You may obtain a copy of the License at
- -
- -   http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing, software
- - distributed under the License is distributed on an "AS IS" BASIS,
- - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- - See the License for the specific language governing permissions and
- - limitations under the License.
- -}
-module Main (main) where
-
-import Language.Python.Common
-
-import Data.XCB.Python.PyHelpers
-
-import Test.Framework ( defaultMain, Test )
-import Test.Framework.Providers.HUnit
-import Test.HUnit hiding ( Test )
-
-mkTest :: (Show a, Eq a) => String -> a -> a -> Test
-mkTest name t1 t2 = testCase name (assertEqual name t1 t2)
-
-testMkName :: Test
-testMkName =
-  let result = mkName "self.foo.bar"
-      expected = (Dot (Dot (Var (Ident "self" ()) ())
-                           (Ident "foo" ()) ())
-                      (Ident "bar" ()) ())
-  in mkTest "testMkName" expected result
-
-testReserves :: Test
-testReserves =
-  let result = mkName "None"
-      expected = (Var (Ident "_None" ()) ())
-  in mkTest "testReserves" expected result
-
-main :: IO ()
-main = do
-  defaultMain [testMkName, testReserves]
diff --git a/tests/generator/enum.py b/tests/generator/enum.py
deleted file mode 100644
--- a/tests/generator/enum.py
+++ /dev/null
@@ -1,39 +0,0 @@
-import xcffib
-import struct
-import six
-_events = {}
-_errors = {}
-class DeviceUse:
-    IsXPointer = 0
-    IsXKeyboard = 1
-    IsXExtensionDevice = 2
-    IsXExtensionKeyboard = 3
-    IsXExtensionPointer = 4
-class EventMask:
-    NoEvent = 0
-    KeyPress = 1 << 0
-    KeyRelease = 1 << 1
-    ButtonPress = 1 << 2
-    ButtonRelease = 1 << 3
-    EnterWindow = 1 << 4
-    LeaveWindow = 1 << 5
-    PointerMotion = 1 << 6
-    PointerMotionHint = 1 << 7
-    Button1Motion = 1 << 8
-    Button2Motion = 1 << 9
-    Button3Motion = 1 << 10
-    Button4Motion = 1 << 11
-    Button5Motion = 1 << 12
-    ButtonMotion = 1 << 13
-    KeymapState = 1 << 14
-    Exposure = 1 << 15
-    VisibilityChange = 1 << 16
-    StructureNotify = 1 << 17
-    ResizeRedirect = 1 << 18
-    SubstructureNotify = 1 << 19
-    SubstructureRedirect = 1 << 20
-    FocusChange = 1 << 21
-    PropertyChange = 1 << 22
-    ColorMapChange = 1 << 23
-    OwnerGrabButton = 1 << 24
-xcffib._add_ext(key, enumExtension, _events, _errors)
diff --git a/tests/generator/enum.xml b/tests/generator/enum.xml
deleted file mode 100644
--- a/tests/generator/enum.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!-- based on xproto -->
-<xcb header="enum">
-
-    <enum name="DeviceUse">
-        <item name="IsXPointer">           <value>0</value> </item>
-        <item name="IsXKeyboard">          <value>1</value> </item>
-        <item name="IsXExtensionDevice">   <value>2</value> </item>
-        <item name="IsXExtensionKeyboard"> <value>3</value> </item>
-        <item name="IsXExtensionPointer">  <value>4</value> </item>
-    </enum>
-
-  <enum name="EventMask">
-    <item name="NoEvent">           <value>0</value></item>
-    <item name="KeyPress">            <bit>0</bit></item>
-    <item name="KeyRelease">          <bit>1</bit></item>
-    <item name="ButtonPress">         <bit>2</bit></item>
-    <item name="ButtonRelease">       <bit>3</bit></item>
-    <item name="EnterWindow">         <bit>4</bit></item>
-    <item name="LeaveWindow">         <bit>5</bit></item>
-    <item name="PointerMotion">       <bit>6</bit></item>
-    <item name="PointerMotionHint">   <bit>7</bit></item>
-    <item name="Button1Motion">       <bit>8</bit></item>
-    <item name="Button2Motion">       <bit>9</bit></item>
-    <item name="Button3Motion">       <bit>10</bit></item>
-    <item name="Button4Motion">       <bit>11</bit></item>
-    <item name="Button5Motion">       <bit>12</bit></item>
-    <item name="ButtonMotion">        <bit>13</bit></item>
-    <item name="KeymapState">         <bit>14</bit></item>
-    <item name="Exposure">            <bit>15</bit></item>
-    <item name="VisibilityChange">    <bit>16</bit></item>
-    <item name="StructureNotify">     <bit>17</bit></item>
-    <item name="ResizeRedirect">      <bit>18</bit></item>
-    <item name="SubstructureNotify">  <bit>19</bit></item>
-    <item name="SubstructureRedirect"><bit>20</bit></item>
-    <item name="FocusChange">         <bit>21</bit></item>
-    <item name="PropertyChange">      <bit>22</bit></item>
-    <item name="ColorMapChange">      <bit>23</bit></item>
-    <item name="OwnerGrabButton">     <bit>24</bit></item>
-  </enum>
-
-</xcb>
diff --git a/tests/generator/error.py b/tests/generator/error.py
deleted file mode 100644
--- a/tests/generator/error.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import xcffib
-import struct
-import six
-MAJOR_VERSION = 2
-MINOR_VERSION = 2
-key = xcffib.ExtensionKey("ERROR")
-_events = {}
-_errors = {}
-class RequestError(xcffib.Error):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Error.__init__(self, unpacker)
-        base = unpacker.offset
-        self.bad_value, self.minor_opcode, self.major_opcode = unpacker.unpack("xx2xIHBx")
-        self.bufsize = unpacker.offset - base
-    def pack(self):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=B", 1))
-        buf.write(struct.pack("=x2xIHBx", self.bad_value, self.minor_opcode, self.major_opcode))
-        return buf.getvalue()
-BadRequest = RequestError
-_errors[1] = RequestError
-xcffib._add_ext(key, errorExtension, _events, _errors)
diff --git a/tests/generator/error.xml b/tests/generator/error.xml
deleted file mode 100644
--- a/tests/generator/error.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<!-- stolen from xv -->
-<xcb header="error" extension-xname="ERROR" extension-name="Error"
-    major-version="2" minor-version="2">
-
-  <error name="Request" number="1">
-    <field type="CARD32" name="bad_value" />
-    <field type="CARD16" name="minor_opcode" />
-    <field type="CARD8" name="major_opcode" />
-    <pad bytes="1" />
-  </error>
-</xcb>
diff --git a/tests/generator/event.py b/tests/generator/event.py
deleted file mode 100644
--- a/tests/generator/event.py
+++ /dev/null
@@ -1,41 +0,0 @@
-import xcffib
-import struct
-import six
-MAJOR_VERSION = 1
-MINOR_VERSION = 4
-key = xcffib.ExtensionKey("EVENT")
-_events = {}
-_errors = {}
-class ScreenChangeNotifyEvent(xcffib.Event):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Event.__init__(self, unpacker)
-        base = unpacker.offset
-        self.rotation, self.timestamp, self.config_timestamp, self.root, self.request_window, self.sizeID, self.subpixel_order, self.width, self.height, self.mwidth, self.mheight = unpacker.unpack("xB2xIIIIHHHHHH")
-        self.bufsize = unpacker.offset - base
-    def pack(self):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=B", 0))
-        buf.write(struct.pack("=B2xIIIIHHHHHH", self.rotation, self.timestamp, self.config_timestamp, self.root, self.request_window, self.sizeID, self.subpixel_order, self.width, self.height, self.mwidth, self.mheight))
-        buf_len = len(buf.getvalue())
-        if buf_len < 32:
-            buf.write(struct.pack("x" * (32 - buf_len)))
-        return buf.getvalue()
-    @classmethod
-    def synthetic(cls, rotation, timestamp, config_timestamp, root, request_window, sizeID, subpixel_order, width, height, mwidth, mheight):
-        self = cls.__new__(cls)
-        self.rotation = rotation
-        self.timestamp = timestamp
-        self.config_timestamp = config_timestamp
-        self.root = root
-        self.request_window = request_window
-        self.sizeID = sizeID
-        self.subpixel_order = subpixel_order
-        self.width = width
-        self.height = height
-        self.mwidth = mwidth
-        self.mheight = mheight
-        return self
-_events[0] = ScreenChangeNotifyEvent
-xcffib._add_ext(key, eventExtension, _events, _errors)
diff --git a/tests/generator/event.xml b/tests/generator/event.xml
deleted file mode 100644
--- a/tests/generator/event.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!-- stolen from randr -->
-<xcb header="event" extension-xname="EVENT" extension-name="Event"
-    major-version="1" minor-version="4">
-
-  <xidtype name="WINDOW" />
-  <typedef oldname="CARD32" newname="TIMESTAMP" />
-
-  <event name="ScreenChangeNotify" number="0">
-    <field type="CARD8" name="rotation" mask="Rotation" />
-    <field type="TIMESTAMP" name="timestamp" />
-    <field type="TIMESTAMP" name="config_timestamp" />
-    <field type="WINDOW" name="root" />
-    <field type="WINDOW" name="request_window" />
-    <field type="CARD16" name="sizeID" />
-    <field type="CARD16" name="subpixel_order" enum="SubPixel" />
-    <field type="CARD16" name="width" />
-    <field type="CARD16" name="height" />
-    <field type="CARD16" name="mwidth" />
-    <field type="CARD16" name="mheight" />
-  </event>
-</xcb>
diff --git a/tests/generator/no_sequence.py b/tests/generator/no_sequence.py
deleted file mode 100644
--- a/tests/generator/no_sequence.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import xcffib
-import struct
-import six
-_events = {}
-_errors = {}
-class KeymapNotifyEvent(xcffib.Event):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Event.__init__(self, unpacker)
-        base = unpacker.offset
-        unpacker.unpack("x")
-        self.keys = xcffib.List(unpacker, "B", 31)
-        self.bufsize = unpacker.offset - base
-    def pack(self):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=B", 11))
-        buf.write(xcffib.pack_list(self.keys, "B"))
-        buf_len = len(buf.getvalue())
-        if buf_len < 32:
-            buf.write(struct.pack("x" * (32 - buf_len)))
-        return buf.getvalue()
-    @classmethod
-    def synthetic(cls, keys):
-        self = cls.__new__(cls)
-        self.keys = keys
-        return self
-_events[11] = KeymapNotifyEvent
-xcffib._add_ext(key, no_sequenceExtension, _events, _errors)
diff --git a/tests/generator/no_sequence.xml b/tests/generator/no_sequence.xml
deleted file mode 100644
--- a/tests/generator/no_sequence.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<xcb header="no_sequence">
-  <event name="KeymapNotify" number="11" no-sequence-number="true">
-    <list type="CARD8" name="keys"><value>31</value></list>
-  </event>
-</xcb>
diff --git a/tests/generator/render.py b/tests/generator/render.py
deleted file mode 100644
--- a/tests/generator/render.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import xcffib
-import struct
-import six
-MAJOR_VERSION = 0
-MINOR_VERSION = 11
-key = xcffib.ExtensionKey("RENDER")
-_events = {}
-_errors = {}
-class COLOR(xcffib.Struct):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Struct.__init__(self, unpacker)
-        base = unpacker.offset
-        self.red, self.green, self.blue, self.alpha = unpacker.unpack("HHHH")
-        self.bufsize = unpacker.offset - base
-    def pack(self):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=HHHH", self.red, self.green, self.blue, self.alpha))
-        return buf.getvalue()
-    fixed_size = 8
-    @classmethod
-    def synthetic(cls, red, green, blue, alpha):
-        self = cls.__new__(cls)
-        self.red = red
-        self.green = green
-        self.blue = blue
-        self.alpha = alpha
-        return self
-class RECTANGLE(xcffib.Struct):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Struct.__init__(self, unpacker)
-        base = unpacker.offset
-        self.x, self.y, self.width, self.height = unpacker.unpack("hhHH")
-        self.bufsize = unpacker.offset - base
-    def pack(self):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=hhHH", self.x, self.y, self.width, self.height))
-        return buf.getvalue()
-    fixed_size = 8
-    @classmethod
-    def synthetic(cls, x, y, width, height):
-        self = cls.__new__(cls)
-        self.x = x
-        self.y = y
-        self.width = width
-        self.height = height
-        return self
-class renderExtension(xcffib.Extension):
-    def FillRectangles(self, op, dst, color, rects_len, rects, is_checked=False):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=xx2xB3xI", op, dst))
-        buf.write(color.pack() if hasattr(color, "pack") else COLOR.synthetic(*color).pack())
-        buf.write("")
-        buf.write(xcffib.pack_list(rects, RECTANGLE))
-        return self.send_request(26, buf, is_checked=is_checked)
-xcffib._add_ext(key, renderExtension, _events, _errors)
diff --git a/tests/generator/render.xml b/tests/generator/render.xml
deleted file mode 100644
--- a/tests/generator/render.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<xcb header="render" extension-xname="RENDER" extension-name="Render"
-    major-version="0" minor-version="11">
-
-  <struct name="COLOR">
-    <field type="CARD16" name="red" />
-    <field type="CARD16" name="green" />
-    <field type="CARD16" name="blue" />
-    <field type="CARD16" name="alpha" />
-  </struct>
-
-  <xidtype name="PICTURE" />
-
-  <struct name="RECTANGLE">
-    <field type="INT16" name="x" />
-    <field type="INT16" name="y" />
-    <field type="CARD16" name="width" />
-    <field type="CARD16" name="height" />
-  </struct>
-
-  <request name="FillRectangles" opcode="26">
-    <field type="CARD8" name="op" enum="PictOp" />
-    <pad bytes="3" />
-    <field type="PICTURE" name="dst" />
-    <field type="COLOR" name="color" />
-    <list type="RECTANGLE" name="rects" />
-  </request>
-</xcb>
diff --git a/tests/generator/render_1.7.py b/tests/generator/render_1.7.py
deleted file mode 100644
--- a/tests/generator/render_1.7.py
+++ /dev/null
@@ -1,63 +0,0 @@
-import xcffib
-import struct
-import six
-MAJOR_VERSION = 0
-MINOR_VERSION = 11
-key = xcffib.ExtensionKey("RENDER")
-_events = {}
-_errors = {}
-class PictOp:
-    Clear = 0
-    Src = 1
-    Dst = 2
-    Over = 3
-    OverReverse = 4
-    In = 5
-    InReverse = 6
-    Out = 7
-    OutReverse = 8
-    Atop = 9
-    AtopReverse = 10
-    Xor = 11
-    Add = 12
-    Saturate = 13
-    DisjointClear = 16
-    DisjointSrc = 17
-    DisjointDst = 18
-    DisjointOver = 19
-    DisjointOverReverse = 20
-    DisjointIn = 21
-    DisjointInReverse = 22
-    DisjointOut = 23
-    DisjointOutReverse = 24
-    DisjointAtop = 25
-    DisjointAtopReverse = 26
-    DisjointXor = 27
-    ConjointClear = 32
-    ConjointSrc = 33
-    ConjointDst = 34
-    ConjointOver = 35
-    ConjointOverReverse = 36
-    ConjointIn = 37
-    ConjointInReverse = 38
-    ConjointOut = 39
-    ConjointOutReverse = 40
-    ConjointAtop = 41
-    ConjointAtopReverse = 42
-    ConjointXor = 43
-    Multiply = 48
-    Screen = 49
-    Overlay = 50
-    Darken = 51
-    Lighten = 52
-    ColorDodge = 53
-    ColorBurn = 54
-    HardLight = 55
-    SoftLight = 56
-    Difference = 57
-    Exclusion = 58
-    HSLHue = 59
-    HSLSaturation = 60
-    HSLColor = 61
-    HSLLuminosity = 62
-xcffib._add_ext(key, render_1._7Extension, _events, _errors)
diff --git a/tests/generator/render_1.7.xml b/tests/generator/render_1.7.xml
deleted file mode 100644
--- a/tests/generator/render_1.7.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<!-- rendering of this enum in xcb-proto 1.7 is vastly more complicated than in
-     more modern versions of xcb-proto, but for completness we should render
-     this correctly as well -->
-<?xml version="1.0" encoding="utf-8"?>
-<xcb header="render_1.7" extension-xname="RENDER" extension-name="Render"
-    major-version="0" minor-version="11">
-
-  <!-- Disjoint* and Conjoint* are new in version 0.2 -->
-  <!-- PDF blend modes are new in version 0.11 -->
-  <enum name="PictOp">
-    <item name="Clear" />
-    <item name="Src" />
-    <item name="Dst" />
-    <item name="Over" />
-    <item name="OverReverse" />
-    <item name="In" />
-    <item name="InReverse" />
-    <item name="Out" />
-    <item name="OutReverse" />
-    <item name="Atop" />
-    <item name="AtopReverse" />
-    <item name="Xor" />
-    <item name="Add" />
-    <item name="Saturate" />
-    
-    <item name="DisjointClear"><value>16</value></item>
-    <item name="DisjointSrc" />
-    <item name="DisjointDst" />
-    <item name="DisjointOver" />
-    <item name="DisjointOverReverse" />
-    <item name="DisjointIn" />
-    <item name="DisjointInReverse" />
-    <item name="DisjointOut" />
-    <item name="DisjointOutReverse" />
-    <item name="DisjointAtop" />
-    <item name="DisjointAtopReverse" />
-    <item name="DisjointXor" />
-    
-    <item name="ConjointClear"><value>32</value></item>
-    <item name="ConjointSrc" />
-    <item name="ConjointDst" />
-    <item name="ConjointOver" />
-    <item name="ConjointOverReverse" />
-    <item name="ConjointIn" />
-    <item name="ConjointInReverse" />
-    <item name="ConjointOut" />
-    <item name="ConjointOutReverse" />
-    <item name="ConjointAtop" />
-    <item name="ConjointAtopReverse" />
-    <item name="ConjointXor" />
-
-    <!-- PDF blend modes are new in version 0.11 -->
-    <item name="Multiply"><value>48</value></item>
-    <item name="Screen" />
-    <item name="Overlay" />
-    <item name="Darken" />
-    <item name="Lighten" />
-    <item name="ColorDodge" />
-    <item name="ColorBurn" />
-    <item name="HardLight" />
-    <item name="SoftLight" />
-    <item name="Difference" />
-    <item name="Exclusion" />
-    <item name="HSLHue" />
-    <item name="HSLSaturation" />
-    <item name="HSLColor" />
-    <item name="HSLLuminosity" />
-  </enum>
-</xcb>
diff --git a/tests/generator/request.py b/tests/generator/request.py
deleted file mode 100644
--- a/tests/generator/request.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import xcffib
-import struct
-import six
-_events = {}
-_errors = {}
-class requestExtension(xcffib.Extension):
-    def CreateWindow(self, depth, wid, parent, x, y, width, height, border_width, _class, visual, value_mask, value_list, is_checked=False):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=xx2xBIIhhHHHHI", depth, wid, parent, x, y, width, height, border_width, _class, visual))
-        buf.write(struct.pack("=I", value_mask))
-        buf.write(xcffib.pack_list(value_list, "I"))
-        return self.send_request(1, buf, is_checked=is_checked)
-xcffib._add_ext(key, requestExtension, _events, _errors)
diff --git a/tests/generator/request.xml b/tests/generator/request.xml
deleted file mode 100644
--- a/tests/generator/request.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<!-- based on xproto -->
-<xcb header="request">
-
-  <xidtype name="WINDOW" />
-  <typedef oldname="CARD32" newname="TIMESTAMP" />
-  <typedef oldname="CARD32" newname="VISUALID" />
-
-  <request name="CreateWindow" opcode="1">
-    <field type="CARD8" name="depth" />
-    <field type="WINDOW" name="wid" />
-    <field type="WINDOW" name="parent" />
-    <field type="INT16" name="x" />
-    <field type="INT16" name="y" />
-    <field type="CARD16" name="width" />
-    <field type="CARD16" name="height" />
-    <field type="CARD16" name="border_width" />
-    <field type="CARD16" name="class" enum="WindowClass" />
-    <field type="VISUALID" name="visual" />
-    <valueparam value-mask-type="CARD32"
-                value-mask-name="value_mask"
-                value-list-name="value_list" />
-    <doc>
-      <brief>Creates a window</brief>
-      <description><![CDATA[
-Creates an unmapped window as child of the specified `parent` window. A
-CreateNotify event will be generated. The new window is placed on top in the
-stacking order with respect to siblings.
-
-The coordinate system has the X axis horizontal and the Y axis vertical with
-the origin [0, 0] at the upper-left corner. Coordinates are integral, in terms
-of pixels, and coincide with pixel centers. Each window and pixmap has its own
-coordinate system. For a window, the origin is inside the border at the inside,
-upper-left corner.
-
-The created window is not yet displayed (mapped), call `xcb_map_window` to
-display it.
-
-The created window will initially use the same cursor as its parent.
-      ]]></description>
-      <field name="wid"><![CDATA[
-The ID with which you will refer to the new window, created by
-`xcb_generate_id`.
-      ]]></field>
-      <field name="depth"><![CDATA[
-Specifies the new window's depth.
-
-The special value `XCB_COPY_FROM_PARENT` means the depth is taken from the
-`parent` window.
-      ]]></field>
-      <field name="visual"><![CDATA[
-Specifies the id for the new window's visual.
-
-The special value `XCB_COPY_FROM_PARENT` means the visual is taken from the
-`parent` window.
-      ]]></field>
-      <field name="class"></field>
-      <field name="parent"><![CDATA[
-The parent window of the new window.
-      ]]></field>
-      <field name="border_width"><![CDATA[
-
-Must be zero if the `class` is `InputOnly` or a `xcb_match_error_t` occurs.
-      ]]></field>
-      <field name="x"><![CDATA[The X coordinate of the new window.]]></field>
-      <field name="y"><![CDATA[The Y coordinate of the new window.]]></field>
-      <field name="width"><![CDATA[The width of the new window.]]></field>
-      <field name="height"><![CDATA[The height of the new window.]]></field>
-      <error type="Colormap"><![CDATA[
-      ]]></error>
-      <error type="Match"><![CDATA[
-      ]]></error>
-      <error type="Cursor"><![CDATA[
-      ]]></error>
-      <error type="Pixmap"><![CDATA[
-      ]]></error>
-      <error type="Value"><![CDATA[
-      ]]></error>
-      <error type="Window"><![CDATA[
-      ]]></error>
-      <error type="Alloc"><![CDATA[
-The X server could not allocate the requested resources (no memory?).
-      ]]></error>
-      <see type="function" name="xcb_generate_id" />
-      <see type="request" name="MapWindow" />
-      <see type="event" name="CreateNotify" />
-    </doc>
-
-  </request>
-
-</xcb>
diff --git a/tests/generator/request_reply.py b/tests/generator/request_reply.py
deleted file mode 100644
--- a/tests/generator/request_reply.py
+++ /dev/null
@@ -1,42 +0,0 @@
-import xcffib
-import struct
-import six
-_events = {}
-_errors = {}
-class STR(xcffib.Struct):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Struct.__init__(self, unpacker)
-        base = unpacker.offset
-        self.name_len, = unpacker.unpack("B")
-        self.name = xcffib.List(unpacker, "c", self.name_len)
-        self.bufsize = unpacker.offset - base
-    def pack(self):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=B", self.name_len))
-        buf.write(xcffib.pack_list(self.name, "c"))
-        return buf.getvalue()
-    @classmethod
-    def synthetic(cls, name_len, name):
-        self = cls.__new__(cls)
-        self.name_len = name_len
-        self.name = name
-        return self
-class ListExtensionsReply(xcffib.Reply):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Reply.__init__(self, unpacker)
-        base = unpacker.offset
-        self.names_len, = unpacker.unpack("xB2x4x24x")
-        self.names = xcffib.List(unpacker, STR, self.names_len)
-        self.bufsize = unpacker.offset - base
-class ListExtensionsCookie(xcffib.Cookie):
-    reply_type = ListExtensionsReply
-class request_replyExtension(xcffib.Extension):
-    def ListExtensions(self, is_checked=True):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=xx2x"))
-        return self.send_request(99, buf, ListExtensionsCookie, is_checked=is_checked)
-xcffib._add_ext(key, request_replyExtension, _events, _errors)
diff --git a/tests/generator/request_reply.xml b/tests/generator/request_reply.xml
deleted file mode 100644
--- a/tests/generator/request_reply.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!-- based on xproto -->
-<xcb header="request_reply">
-
-  <struct name="STR">
-    <field type="CARD8" name="name_len" />
-    <list type="char" name="name">
-      <fieldref>name_len</fieldref>
-    </list>
-  </struct>
-
-  <request name="ListExtensions" opcode="99">
-    <reply>
-      <field type="CARD8" name="names_len" />
-      <pad bytes="24" />
-      <list type="STR" name="names">
-        <fieldref>names_len</fieldref>
-      </list>
-    </reply>
-  </request>
-
-</xcb>
diff --git a/tests/generator/struct.py b/tests/generator/struct.py
deleted file mode 100644
--- a/tests/generator/struct.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import xcffib
-import struct
-import six
-_events = {}
-_errors = {}
-class AxisInfo(xcffib.Struct):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Struct.__init__(self, unpacker)
-        base = unpacker.offset
-        self.resolution, self.minimum, self.maximum = unpacker.unpack("Iii")
-        self.bufsize = unpacker.offset - base
-    def pack(self):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=Iii", self.resolution, self.minimum, self.maximum))
-        return buf.getvalue()
-    fixed_size = 12
-    @classmethod
-    def synthetic(cls, resolution, minimum, maximum):
-        self = cls.__new__(cls)
-        self.resolution = resolution
-        self.minimum = minimum
-        self.maximum = maximum
-        return self
-class ValuatorInfo(xcffib.Struct):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Struct.__init__(self, unpacker)
-        base = unpacker.offset
-        self.class_id, self.len, self.axes_len, self.mode, self.motion_size = unpacker.unpack("BBBBI")
-        self.axes = xcffib.List(unpacker, AxisInfo, self.axes_len)
-        self.bufsize = unpacker.offset - base
-    def pack(self):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=BBBBI", self.class_id, self.len, self.axes_len, self.mode, self.motion_size))
-        buf.write(xcffib.pack_list(self.axes, AxisInfo))
-        return buf.getvalue()
-    @classmethod
-    def synthetic(cls, class_id, len, axes_len, mode, motion_size, axes):
-        self = cls.__new__(cls)
-        self.class_id = class_id
-        self.len = len
-        self.axes_len = axes_len
-        self.mode = mode
-        self.motion_size = motion_size
-        self.axes = axes
-        return self
-xcffib._add_ext(key, structExtension, _events, _errors)
diff --git a/tests/generator/struct.xml b/tests/generator/struct.xml
deleted file mode 100644
--- a/tests/generator/struct.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!-- based on xproto -->
-<xcb header="struct">
-
-    <struct name="AxisInfo">
-        <field type="CARD32" name="resolution" />
-        <field type="INT32"  name="minimum" />
-        <field type="INT32"  name="maximum" />
-    </struct>
-
-    <struct name="ValuatorInfo">
-        <field type="CARD8"   name="class_id" enum="InputClass" />
-        <field type="CARD8"   name="len" />
-        <field type="CARD8"   name="axes_len" />
-        <field type="CARD8"   name="mode" enum="ValuatorMode" />
-        <field type="CARD32"  name="motion_size" />
-        <list type="AxisInfo" name="axes">
-            <fieldref>axes_len</fieldref>
-        </list>
-    </struct>
-
-</xcb>
diff --git a/tests/generator/type_pad.py b/tests/generator/type_pad.py
deleted file mode 100644
--- a/tests/generator/type_pad.py
+++ /dev/null
@@ -1,73 +0,0 @@
-import xcffib
-import struct
-import six
-_events = {}
-_errors = {}
-class CHARINFO(xcffib.Struct):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Struct.__init__(self, unpacker)
-        base = unpacker.offset
-        self.left_side_bearing, self.right_side_bearing, self.character_width, self.ascent, self.descent, self.attributes = unpacker.unpack("hhhhhH")
-        self.bufsize = unpacker.offset - base
-    def pack(self):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=hhhhhH", self.left_side_bearing, self.right_side_bearing, self.character_width, self.ascent, self.descent, self.attributes))
-        return buf.getvalue()
-    fixed_size = 12
-    @classmethod
-    def synthetic(cls, left_side_bearing, right_side_bearing, character_width, ascent, descent, attributes):
-        self = cls.__new__(cls)
-        self.left_side_bearing = left_side_bearing
-        self.right_side_bearing = right_side_bearing
-        self.character_width = character_width
-        self.ascent = ascent
-        self.descent = descent
-        self.attributes = attributes
-        return self
-class FONTPROP(xcffib.Struct):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Struct.__init__(self, unpacker)
-        base = unpacker.offset
-        self.name, self.value = unpacker.unpack("II")
-        self.bufsize = unpacker.offset - base
-    def pack(self):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=II", self.name, self.value))
-        return buf.getvalue()
-    fixed_size = 8
-    @classmethod
-    def synthetic(cls, name, value):
-        self = cls.__new__(cls)
-        self.name = name
-        self.value = value
-        return self
-class ListFontsWithInfoReply(xcffib.Reply):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Reply.__init__(self, unpacker)
-        base = unpacker.offset
-        self.name_len, = unpacker.unpack("xB2x4x")
-        self.min_bounds = CHARINFO(unpacker)
-        unpacker.unpack("4x")
-        unpacker.pad(CHARINFO)
-        self.max_bounds = CHARINFO(unpacker)
-        self.min_char_or_byte2, self.max_char_or_byte2, self.default_char, self.properties_len, self.draw_direction, self.min_byte1, self.max_byte1, self.all_chars_exist, self.font_ascent, self.font_descent, self.replies_hint = unpacker.unpack("4xHHHHBBBBhhI")
-        unpacker.pad(FONTPROP)
-        self.properties = xcffib.List(unpacker, FONTPROP, self.properties_len)
-        unpacker.pad("c")
-        self.name = xcffib.List(unpacker, "c", self.name_len)
-        self.bufsize = unpacker.offset - base
-class ListFontsWithInfoCookie(xcffib.Cookie):
-    reply_type = ListFontsWithInfoReply
-class type_padExtension(xcffib.Extension):
-    def ListFontsWithInfo(self, max_names, pattern_len, pattern, is_checked=True):
-        buf = six.BytesIO()
-        buf.write(struct.pack("=xx2xxHH", max_names, pattern_len))
-        buf.write(xcffib.pack_list(pattern, "c"))
-        return self.send_request(50, buf, ListFontsWithInfoCookie, is_checked=is_checked)
-xcffib._add_ext(key, type_padExtension, _events, _errors)
diff --git a/tests/generator/type_pad.xml b/tests/generator/type_pad.xml
deleted file mode 100644
--- a/tests/generator/type_pad.xml
+++ /dev/null
@@ -1,111 +0,0 @@
-<xcb header="type_pad">
-
-  <struct name="CHARINFO">
-    <field type="INT16" name="left_side_bearing" />
-    <field type="INT16" name="right_side_bearing" />
-    <field type="INT16" name="character_width" />
-    <field type="INT16" name="ascent" />
-    <field type="INT16" name="descent" />
-    <field type="CARD16" name="attributes" />
-  </struct>
-
-  <xidtype name="ATOM" />
-
-  <struct name="FONTPROP">
-    <field type="ATOM" name="name" />
-    <field type="CARD32" name="value" />
-  </struct>
-
-  <request name="ListFontsWithInfo" opcode="50">
-    <pad bytes="1" />
-    <field type="CARD16" name="max_names" />
-    <field type="CARD16" name="pattern_len" />
-    <list type="char" name="pattern">
-      <fieldref>pattern_len</fieldref>
-    </list>
-    <reply>
-      <field type="CARD8" name="name_len" />
-      <field type="CHARINFO" name="min_bounds" />
-      <pad bytes="4" />
-      <field type="CHARINFO" name="max_bounds" />
-      <pad bytes="4" />
-      <field type="CARD16" name="min_char_or_byte2" />
-      <field type="CARD16" name="max_char_or_byte2" />
-      <field type="CARD16" name="default_char" />
-      <field type="CARD16" name="properties_len" />
-      <field type="BYTE" name="draw_direction" enum="FontDraw" />
-      <field type="CARD8" name="min_byte1" />
-      <field type="CARD8" name="max_byte1" />
-      <field type="BOOL" name="all_chars_exist" />
-      <field type="INT16" name="font_ascent" />
-      <field type="INT16" name="font_descent" />
-      <field type="CARD32" name="replies_hint" />
-      <list type="FONTPROP" name="properties">
-        <fieldref>properties_len</fieldref>
-      </list>
-      <list type="char" name="name">
-        <fieldref>name_len</fieldref>
-      </list>
-      <doc>
-        <field name="name_len"><![CDATA[
-The number of matched font names.
-        ]]></field>
-        <field name="min_bounds"><![CDATA[
-minimum bounds over all existing char
-        ]]></field>
-        <field name="max_bounds"><![CDATA[
-maximum bounds over all existing char
-        ]]></field>
-        <field name="min_char_or_byte2"><![CDATA[
-first character
-        ]]></field>
-        <field name="max_char_or_byte2"><![CDATA[
-last character
-        ]]></field>
-        <field name="default_char"><![CDATA[
-char to print for undefined character
-        ]]></field>
-        <field name="properties_len"><![CDATA[
-how many properties there are
-        ]]></field>
-        <field name="all_chars_exist"><![CDATA[
-flag if all characters have nonzero size
-        ]]></field>
-        <field name="font_ascent"><![CDATA[
-baseline to top edge of raster
-        ]]></field>
-        <field name="font_descent"><![CDATA[
-baseline to bottom edge of raster
-        ]]></field>
-        <field name="replies_hint"><![CDATA[
-An indication of how many more fonts will be returned. This is only a hint and
-may be larger or smaller than the number of fonts actually returned. A zero
-value does not guarantee that no more fonts will be returned.
-        ]]></field>
-        <!-- enum doc is sufficient -->
-        <field name="draw_direction" />
-      </doc>
-    </reply>
-    <doc>
-      <brief>get matching font names and information</brief>
-      <description><![CDATA[
-Gets a list of available font names which match the given `pattern`.
-      ]]></description>
-      <field name="pattern_len"><![CDATA[
-The length (in bytes) of `pattern`.
-      ]]></field>
-      <field name="pattern"><![CDATA[
-A font pattern, for example "-misc-fixed-*".
-
-The asterisk (*) is a wildcard for any number of characters. The question mark
-(?) is a wildcard for a single character. Use of uppercase or lowercase does
-not matter.
-      ]]></field>
-      <field name="max_names"><![CDATA[
-The maximum number of fonts to be returned.
-      ]]></field>
-    </doc>
-
-  </request>
-
-</xcb>
diff --git a/tests/generator/union.py b/tests/generator/union.py
deleted file mode 100644
--- a/tests/generator/union.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import xcffib
-import struct
-import six
-_events = {}
-_errors = {}
-class ClientMessageData(xcffib.Union):
-    def __init__(self, unpacker):
-        if isinstance(unpacker, xcffib.Protobj):
-            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
-        xcffib.Union.__init__(self, unpacker)
-        self.data8 = xcffib.List(unpacker.copy(), "B", 20)
-        self.data16 = xcffib.List(unpacker.copy(), "H", 10)
-        self.data32 = xcffib.List(unpacker.copy(), "I", 5)
-    def pack(self):
-        buf = six.BytesIO()
-        buf.write(xcffib.pack_list(self.data8, "B"))
-        return buf.getvalue()
-xcffib._add_ext(key, unionExtension, _events, _errors)
diff --git a/tests/generator/union.xml b/tests/generator/union.xml
deleted file mode 100644
--- a/tests/generator/union.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<!-- based on xproto -->
-<xcb header="union">
-
-  <union name="ClientMessageData">
-    <!-- The format member of the ClientMessage event determines which array
-         to use. -->
-    <list type="CARD8"  name="data8" ><value>20</value></list> <!--  8 -->
-    <list type="CARD16" name="data16"><value>10</value></list> <!-- 16 -->
-    <list type="CARD32" name="data32"><value>5</value></list>  <!-- 32 -->
-  </union>
-
-</xcb>
diff --git a/tests/generator/xproto_1.7.py b/tests/generator/xproto_1.7.py
deleted file mode 100644
--- a/tests/generator/xproto_1.7.py
+++ /dev/null
@@ -1,80 +0,0 @@
-import xcffib
-import struct
-import six
-MAJOR_VERSION = 0
-MINOR_VERSION = 11
-key = xcffib.ExtensionKey("XPROTO")
-_events = {}
-_errors = {}
-class Atom:
-    _None = 0
-    Any = 0
-    PRIMARY = 1
-    SECONDARY = 2
-    ARC = 3
-    ATOM = 4
-    BITMAP = 5
-    CARDINAL = 6
-    COLORMAP = 7
-    CURSOR = 8
-    CUT_BUFFER0 = 9
-    CUT_BUFFER1 = 10
-    CUT_BUFFER2 = 11
-    CUT_BUFFER3 = 12
-    CUT_BUFFER4 = 13
-    CUT_BUFFER5 = 14
-    CUT_BUFFER6 = 15
-    CUT_BUFFER7 = 16
-    DRAWABLE = 17
-    FONT = 18
-    INTEGER = 19
-    PIXMAP = 20
-    POINT = 21
-    RECTANGLE = 22
-    RESOURCE_MANAGER = 23
-    RGB_COLOR_MAP = 24
-    RGB_BEST_MAP = 25
-    RGB_BLUE_MAP = 26
-    RGB_DEFAULT_MAP = 27
-    RGB_GRAY_MAP = 28
-    RGB_GREEN_MAP = 29
-    RGB_RED_MAP = 30
-    STRING = 31
-    VISUALID = 32
-    WINDOW = 33
-    WM_COMMAND = 34
-    WM_HINTS = 35
-    WM_CLIENT_MACHINE = 36
-    WM_ICON_NAME = 37
-    WM_ICON_SIZE = 38
-    WM_NAME = 39
-    WM_NORMAL_HINTS = 40
-    WM_SIZE_HINTS = 41
-    WM_ZOOM_HINTS = 42
-    MIN_SPACE = 43
-    NORM_SPACE = 44
-    MAX_SPACE = 45
-    END_SPACE = 46
-    SUPERSCRIPT_X = 47
-    SUPERSCRIPT_Y = 48
-    SUBSCRIPT_X = 49
-    SUBSCRIPT_Y = 50
-    UNDERLINE_POSITION = 51
-    UNDERLINE_THICKNESS = 52
-    STRIKEOUT_ASCENT = 53
-    STRIKEOUT_DESCENT = 54
-    ITALIC_ANGLE = 55
-    X_HEIGHT = 56
-    QUAD_WIDTH = 57
-    WEIGHT = 58
-    POINT_SIZE = 59
-    RESOLUTION = 60
-    COPYRIGHT = 61
-    NOTICE = 62
-    FONT_NAME = 63
-    FAMILY_NAME = 64
-    FULL_NAME = 65
-    CAP_HEIGHT = 66
-    WM_CLASS = 67
-    WM_TRANSIENT_FOR = 68
-xcffib._add_ext(key, xproto_1._7Extension, _events, _errors)
diff --git a/tests/generator/xproto_1.7.xml b/tests/generator/xproto_1.7.xml
deleted file mode 100644
--- a/tests/generator/xproto_1.7.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<!-- rendering of this enum in xcb-proto 1.7 is vastly more complicated than in
-     more modern versions of xcb-proto, but for completness we should render
-     this correctly as well -->
-<?xml version="1.0" encoding="utf-8"?>
-<xcb header="xproto_1.7" extension-xname="XPROTO" extension-name="xproto"
-    major-version="0" minor-version="11">
-
-  <enum name="Atom">
-    <item name="None"> <value>0</value></item>
-    <item name="Any">  <value>0</value></item>
-    <item name="PRIMARY" />
-    <item name="SECONDARY" />
-    <item name="ARC" />
-    <item name="ATOM" />
-    <item name="BITMAP" />
-    <item name="CARDINAL" />
-    <item name="COLORMAP" />
-    <item name="CURSOR" />
-    <item name="CUT_BUFFER0" />
-    <item name="CUT_BUFFER1" />
-    <item name="CUT_BUFFER2" />
-    <item name="CUT_BUFFER3" />
-    <item name="CUT_BUFFER4" />
-    <item name="CUT_BUFFER5" />
-    <item name="CUT_BUFFER6" />
-    <item name="CUT_BUFFER7" />
-    <item name="DRAWABLE" />
-    <item name="FONT" />
-    <item name="INTEGER" />
-    <item name="PIXMAP" />
-    <item name="POINT" />
-    <item name="RECTANGLE" />
-    <item name="RESOURCE_MANAGER" />
-    <item name="RGB_COLOR_MAP" />
-    <item name="RGB_BEST_MAP" />
-    <item name="RGB_BLUE_MAP" />
-    <item name="RGB_DEFAULT_MAP" />
-    <item name="RGB_GRAY_MAP" />
-    <item name="RGB_GREEN_MAP" />
-    <item name="RGB_RED_MAP" />
-    <item name="STRING" />
-    <item name="VISUALID" />
-    <item name="WINDOW" />
-    <item name="WM_COMMAND" />
-    <item name="WM_HINTS" />
-    <item name="WM_CLIENT_MACHINE" />
-    <item name="WM_ICON_NAME" />
-    <item name="WM_ICON_SIZE" />
-    <item name="WM_NAME" />
-    <item name="WM_NORMAL_HINTS" />
-    <item name="WM_SIZE_HINTS" />
-    <item name="WM_ZOOM_HINTS" />
-    <item name="MIN_SPACE" />
-    <item name="NORM_SPACE" />
-    <item name="MAX_SPACE" />
-    <item name="END_SPACE" />
-    <item name="SUPERSCRIPT_X" />
-    <item name="SUPERSCRIPT_Y" />
-    <item name="SUBSCRIPT_X" />
-    <item name="SUBSCRIPT_Y" />
-    <item name="UNDERLINE_POSITION" />
-    <item name="UNDERLINE_THICKNESS" />
-    <item name="STRIKEOUT_ASCENT" />
-    <item name="STRIKEOUT_DESCENT" />
-    <item name="ITALIC_ANGLE" />
-    <item name="X_HEIGHT" />
-    <item name="QUAD_WIDTH" />
-    <item name="WEIGHT" />
-    <item name="POINT_SIZE" />
-    <item name="RESOLUTION" />
-    <item name="COPYRIGHT" />
-    <item name="NOTICE" />
-    <item name="FONT_NAME" />
-    <item name="FAMILY_NAME" />
-    <item name="FULL_NAME" />
-    <item name="CAP_HEIGHT" />
-    <item name="WM_CLASS" />
-    <item name="WM_TRANSIENT_FOR" />
-  </enum>
-
-</xcb>
diff --git a/xcffib.cabal b/xcffib.cabal
--- a/xcffib.cabal
+++ b/xcffib.cabal
@@ -1,5 +1,5 @@
 name:                xcffib
-version:             0.4.0
+version:             0.4.1
 synopsis:            A cffi-based python binding for X
 homepage:            http://github.com/tych0/xcffib
 license:             OtherLicense
@@ -11,13 +11,13 @@
 cabal-version:       >=1.8
 bug-reports:         https://github.com/tych0/xcffib/issues
 description: A cffi-based python binding for X, comparable to xpyb
-extra-source-files: tests/generator/*.py,
-                    tests/generator/*.xml,
+extra-source-files: test/generator/*.py,
+                    test/generator/*.xml,
                     -- cabal's wildcarding is broken if the filename contains
                     -- extra dots:
                     -- https://github.com/haskell/cabal/issues/784
-                    tests/generator/*.7.py,
-                    tests/generator/*.7.xml
+                    test/generator/*.7.py,
+                    test/generator/*.7.xml
 
 source-repository head
   type:              git
@@ -58,7 +58,7 @@
   ghc-options: -Wall
 
 test-suite PyHelpersTests
-  hs-source-dirs: tests
+  hs-source-dirs: test
   main-is: PyHelpersTests.hs
   type: exitcode-stdio-1.0
   build-depends: base ==4.*,
@@ -69,7 +69,7 @@
                  test-framework-hunit
 
 test-suite GeneratorTests.hs
-  hs-source-dirs: tests
+  hs-source-dirs: test
   main-is: GeneratorTests.hs
   type: exitcode-stdio-1.0
   build-depends: base ==4.*,
