@Override
 public void execute(RatpackServerSpec server) throws Exception {
   RatpackDslClosures closures = new RatpackDslClosures(null);
   RatpackDslBacking backing = new RatpackDslBacking(closures);
   ClosureUtil.configureDelegateFirst(backing, closure);
   server.registry(Guice.registry(ClosureUtil.delegatingAction(closures.getBindings())));
   server.handlers(Groovy.chainAction(closures.getHandlers()));
   ServerConfigBuilder builder = ServerConfig.builder().development(true);
   if (ephemeralPort) {
     builder.port(0);
   }
   ClosureUtil.configureDelegateFirst(builder, closures.getServerConfig());
   server.serverConfig(builder);
 }
/**
 * @see ratpack.test.handling.RequestFixture#handle(ratpack.handling.Handler, ratpack.func.Action)
 */
@SuppressWarnings("UnusedDeclaration")
public class DefaultRequestFixture implements RequestFixture {

  private final ByteBuf requestBody = unreleasableBuffer(buffer());
  private final MutableHeaders requestHeaders =
      new NettyHeadersBackedMutableHeaders(new DefaultHttpHeaders());
  private final NettyHeadersBackedMutableHeaders responseHeaders =
      new NettyHeadersBackedMutableHeaders(new DefaultHttpHeaders());

  private String method = "GET";
  private String protocol = "HTTP/1.1";
  private String uri = "/";
  private HostAndPort remoteHostAndPort = HostAndPort.fromParts("localhost", 45678);
  private HostAndPort localHostAndPort =
      HostAndPort.fromParts("localhost", ServerConfig.DEFAULT_PORT);
  private int timeout = 5;

  private RegistryBuilder registryBuilder = Registry.builder();

  private ServerConfigBuilder serverConfigBuilder = ServerConfig.builder();
  private DefaultPathBinding pathBinding;

  @Override
  public RequestFixture body(byte[] bytes, String contentType) {
    requestHeaders.add(HttpHeaderNames.CONTENT_TYPE, contentType);
    requestHeaders.add(HttpHeaderNames.CONTENT_LENGTH, bytes.length);
    requestBody.capacity(bytes.length).writeBytes(bytes);
    return this;
  }

  @Override
  public RequestFixture body(String text, String contentType) {
    return body(text.getBytes(CharsetUtil.UTF_8), contentType);
  }

  @Override
  public RegistrySpec getRegistry() {
    return registryBuilder;
  }

  @Override
  public HandlingResult handle(Handler handler) throws HandlerTimeoutException {
    final DefaultHandlingResult.ResultsHolder results = new DefaultHandlingResult.ResultsHolder();
    return invoke(handler, getEffectiveRegistry(results), results);
  }

  @Override
  public HandlingResult handleChain(Action<? super Chain> chainAction) throws Exception {
    final DefaultHandlingResult.ResultsHolder results = new DefaultHandlingResult.ResultsHolder();
    Registry registry = getEffectiveRegistry(results);
    ServerConfig serverConfig = registry.get(ServerConfig.class);
    Handler handler = Handlers.chain(serverConfig, registry, chainAction);
    return invoke(handler, registry, results);
  }

  private HandlingResult invoke(
      Handler handler, Registry registry, DefaultHandlingResult.ResultsHolder results)
      throws HandlerTimeoutException {
    ServerConfig serverConfig = registry.get(ServerConfig.class);

    DefaultRequest request =
        new DefaultRequest(
            Instant.now(),
            requestHeaders,
            HttpMethod.valueOf(method.toUpperCase()),
            HttpVersion.valueOf(protocol),
            uri,
            new InetSocketAddress(remoteHostAndPort.getHostText(), remoteHostAndPort.getPort()),
            new InetSocketAddress(localHostAndPort.getHostText(), localHostAndPort.getPort()),
            serverConfig,
            new RequestBodyReader() {
              @Override
              public Promise<? extends ByteBuf> read(long maxContentLength, Block onTooLarge) {
                return Promise.value(requestBody)
                    .route(r -> r.readableBytes() > maxContentLength, onTooLarge.action());
              }

              @Override
              public TransformablePublisher<? extends ByteBuf> readStream(long maxContentLength) {
                return Streams.<ByteBuf>yield(
                    r -> {
                      if (r.getRequestNum() > 0) {
                        return null;
                      } else {
                        return requestBody;
                      }
                    });
              }
            });

    if (pathBinding != null) {
      handler =
          Handlers.chain(
              ctx -> {
                ctx.getExecution().get(PathBindingStorage.TYPE).push(pathBinding);
                ctx.next();
              },
              handler);
    }

    try {
      return new DefaultHandlingResult(
          request, results, responseHeaders, registry, timeout, handler);
    } catch (Exception e) {
      throw Exceptions.uncheck(e);
    } finally {
      registry.get(ExecController.class).close();
    }
  }

  @Override
  public RequestFixture header(CharSequence name, String value) {
    requestHeaders.add(name, value);
    return this;
  }

  @Override
  public RequestFixture serverConfig(Action<? super ServerConfigBuilder> action) throws Exception {
    serverConfigBuilder = ServerConfig.builder();
    action.execute(serverConfigBuilder);
    return this;
  }

  @Override
  public RequestFixture method(String method) {
    if (method == null) {
      throw new IllegalArgumentException("method must not be null");
    }
    this.method = method.toUpperCase();
    return this;
  }

  @Override
  public RequestFixture pathBinding(Map<String, String> pathTokens) {
    return pathBinding("", "", pathTokens);
  }

  @Override
  public RequestFixture pathBinding(
      String boundTo, String pastBinding, Map<String, String> pathTokens) {
    pathBinding =
        new DefaultPathBinding(
            pastBinding, ImmutableMap.copyOf(pathTokens), new RootPathBinding(pastBinding));
    return this;
  }

  @Override
  public RequestFixture registry(Action<? super RegistrySpec> action) throws Exception {
    action.execute(registryBuilder);
    return this;
  }

  @Override
  public RequestFixture responseHeader(CharSequence name, String value) {
    responseHeaders.add(name, value);
    return this;
  }

  @Override
  public RequestFixture timeout(int timeoutSeconds) {
    if (timeoutSeconds < 0) {
      throw new IllegalArgumentException("timeout must be > 0");
    }
    this.timeout = timeoutSeconds;
    return this;
  }

  @Override
  public RequestFixture uri(String uri) {
    if (uri == null) {
      throw new NullPointerException("uri cannot be null");
    }
    if (!uri.startsWith("/")) {
      uri = "/" + uri;
    }

    this.uri = uri;
    return this;
  }

  @Override
  public RequestFixture remoteAddress(HostAndPort remote) {
    remoteHostAndPort = remote;
    return this;
  }

  @Override
  public RequestFixture localAddress(HostAndPort local) {
    localHostAndPort = local;
    return this;
  }

  @Override
  public RequestFixture protocol(String protocol) {
    this.protocol = protocol;
    return this;
  }

  private Registry getEffectiveRegistry(final DefaultHandlingResult.ResultsHolder results) {

    ClientErrorHandler clientErrorHandler =
        (context, statusCode) -> {
          results.setClientError(statusCode);
          context.getResponse().status(statusCode);
          results.getLatch().countDown();
        };

    ServerErrorHandler serverErrorHandler =
        (context, throwable1) -> {
          results.setThrowable(throwable1);
          results.getLatch().countDown();
        };

    final Registry userRegistry =
        Registry.builder()
            .add(ClientErrorHandler.class, clientErrorHandler)
            .add(ServerErrorHandler.class, serverErrorHandler)
            .build();
    return Exceptions.uncheck(
        () -> {
          ServerConfig serverConfig = serverConfigBuilder.build();
          DefaultExecController execController =
              new DefaultExecController(serverConfig.getThreads());
          return ServerRegistry.serverRegistry(
              new TestServer(),
              Impositions.none(),
              execController,
              serverConfig,
              r -> userRegistry.join(registryBuilder.build()));
        });
  }

  // TODO some kind of impl here
  private static class TestServer implements RatpackServer {

    @Override
    public String getScheme() {
      throw new UnsupportedOperationException();
    }

    @Override
    public int getBindPort() {
      throw new UnsupportedOperationException();
    }

    @Override
    public String getBindHost() {
      throw new UnsupportedOperationException();
    }

    @Override
    public boolean isRunning() {
      throw new UnsupportedOperationException();
    }

    @Override
    public void start() throws Exception {
      throw new UnsupportedOperationException();
    }

    @Override
    public void stop() throws Exception {
      throw new UnsupportedOperationException();
    }

    @Override
    public RatpackServer reload() throws Exception {
      throw new UnsupportedOperationException();
    }
  }
}
 @Override
 public RequestFixture serverConfig(Action<? super ServerConfigBuilder> action) throws Exception {
   serverConfigBuilder = ServerConfig.builder();
   action.execute(serverConfigBuilder);
   return this;
 }