new_contents: import pytest
  
  from unittest.mock import Mock
  from collections import namedtuple
  from functools import partial
  import inspect
  import types
  import math
  
  import impl_cffi
  
  testcase_fields = 'data,method,path,version,headers,body'
  
  HttpTestCase = namedtuple('HTTPTestCase', testcase_fields)
  
  http10long = HttpTestCase(
  b"""POST /wp-content/uploads/2010/03/hello-kitty-darth-vader-pink.jpg HTTP/1.0\r
  HOST: www.kittyhell.com\r
  User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ja-JP-mac; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 Pathtraq/0.9\r
  Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r
  Accept-Language: ja,en-us;q=0.7,en;q=0.3\r
  Accept-Encoding: gzip,deflate\r
  Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7\r
  Keep-Alive: 115\r
  Cookie: wp_ozh_wsa_visits=2; wp_ozh_wsa_visit_lasttime=xxxxxxxxxx; __utma=xxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.x; __utmz=xxxxxxxxx.xxxxxxxxxx.x.x.utmccn=(referral)|utmcsr=reader.livedoor.com|utmcct=/reader/|utmcmd=referral\r
  \r
  Hello there""",
  "POST",
  "/wp-content/uploads/2010/03/hello-kitty-darth-vader-pink.jpg",
  "1.0",
  {
      "Host": "www.kittyhell.com",
      "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ja-JP-mac; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 Pathtraq/0.9",
      "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
      "Accept-Language": "ja,en-us;q=0.7,en;q=0.3",
      "Accept-Encoding": "gzip,deflate",
      "Accept-Charset": "Shift_JIS,utf-8;q=0.7,*;q=0.7",
      "Keep-Alive": "115",
      "Cookie": "wp_ozh_wsa_visits=2; wp_ozh_wsa_visit_lasttime=xxxxxxxxxx; __utma=xxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.x; __utmz=xxxxxxxxx.xxxxxxxxxx.x.x.utmccn=(referral)|utmcsr=reader.livedoor.com|utmcct=/reader/|utmcmd=referral"
  },
  b"Hello there"
  )
  
  http10short = HttpTestCase(
  b"""POST / HTTP/1.0\r
  Host: www.example.com\r
  \r
  Hi!""",
  "POST",
  "/",
  "1.0",
  {"Host": "www.example.com"},
  b"Hi!"
  )
  
  def make_parts(value, get_size, dir=1):
      parts = []
  
      left = bytearray(value)
      while left:
          if isinstance(get_size, types.GeneratorType):
              size = next(get_size)
          else:
              size = get_size
  
          if dir == 1:
              parts.append(bytes(left[:size]))
              left = left[size:]
          else:
              parts.append(bytes(left[-size:]))
              left = left[:-size]
  
      return parts if dir == 1 else list(reversed(parts))
  
  
  def one_part(value):
      return [value]
  
  
  def geometric_series():
      s = 2
      while 1:
          yield s
          s *= 2
  
  
  def fancy_series():
      x = 0
      while 1:
          yield int(2 + abs(math.sin(x / 5)) * 64)
          x += 1
  
  
  def make_part_functions():
      return [
          one_part,
          partial(make_parts, get_size=15),
          partial(make_parts, get_size=geometric_series()),
          partial(make_parts, get_size=geometric_series(), dir=-1),
          partial(make_parts, get_size=fancy_series())
      ]
  
  
  @pytest.mark.parametrize('data,get_size,dir,parts',
  [
      (b'abcde', 2, 1, [b'ab', b'cd', b'e']),
      (b'abcde', 2, -1, [b'a', b'bc', b'de']),
      (b'aaBBBBccccCCCCd', geometric_series(), 1,
       [b'aa', b'BBBB', b'ccccCCCC', b'd']),
      (b'dCCCCccccBBBBaa', geometric_series(), -1,
       [b'd', b'CCCCcccc', b'BBBB', b'aa'])
  ])
  def test_make_parts(data, get_size, dir, parts):
      assert make_parts(data, get_size, dir) == parts
  
  
  @pytest.mark.parametrize('do_parts', make_part_functions())
  @pytest.mark.parametrize(testcase_fields, [http10long, http10short])
  def test_http10_one_request(do_parts, data, method, path, version, headers, body):
      on_headers = Mock()
      on_error = Mock()
      on_body = Mock()
      parser = impl_cffi.HttpRequestParser(on_headers, on_error, on_body)
  
      parts = do_parts(data)
  
      for part in parts:
          parser.feed(part)
      parser.feed_disconnect()
  
      assert on_headers.called
      assert not on_error.called
      assert on_body.called
  
      request = on_headers.call_args[0][0]
  
      assert request.method == method
      assert request.path == path
      assert request.version == version
      assert request.headers == headers
      assert request.body == body
  
subject: add functions to make parts and test with parts