// Path: src/main/java/com/github/tonivade/resp/protocol/RedisToken.java
// static RedisToken array(RedisToken... redisTokens) {
//   return new ArrayRedisToken(ImmutableList.of(redisTokens));
// }
// 
// Path: src/main/java/com/github/tonivade/resp/protocol/RedisToken.java
// static RedisToken status(String str) {
//   return new StatusRedisToken(str);
// }
// 
// Path: src/main/java/com/github/tonivade/resp/protocol/RedisToken.java
// static RedisToken string(SafeString str) {
//   return new StringRedisToken(str);
// }
// 
// Path: src/main/java/com/github/tonivade/resp/protocol/RedisToken.java
// public interface RedisToken {
//   RedisToken NULL_STRING = string((SafeString) null);
//   RedisToken RESPONSE_OK = status("OK");
// 
//   RedisTokenType getType();
// 
//   <T> T accept(RedisTokenVisitor<T> visitor);
// 
//   static RedisToken nullString() {
//     return NULL_STRING;
//   }
// 
//   static RedisToken responseOk() {
//     return RESPONSE_OK;
//   }
// 
//   static RedisToken string(SafeString str) {
//     return new StringRedisToken(str);
//   }
// 
//   static RedisToken string(String str) {
//     return new StringRedisToken(safeString(str));
//   }
// 
//   static RedisToken status(String str) {
//     return new StatusRedisToken(str);
//   }
// 
//   static RedisToken integer(boolean b) {
//     return new IntegerRedisToken(b ? 1 : 0);
//   }
// 
//   static RedisToken integer(int i) {
//     return new IntegerRedisToken(i);
//   }
// 
//   static RedisToken error(String str) {
//     return new ErrorRedisToken(str);
//   }
// 
//   static RedisToken array(RedisToken... redisTokens) {
//     return new ArrayRedisToken(ImmutableList.of(redisTokens));
//   }
// 
//   static RedisToken array(Collection<RedisToken> redisTokens) {
//     return new ArrayRedisToken(ImmutableList.from(redisTokens));
//   }
// 
//   static RedisToken array(Sequence<RedisToken> redisTokens) {
//     return new ArrayRedisToken(redisTokens.asArray());
//   }
// 
//   static <T> Stream<T> visit(Stream<RedisToken> tokens, RedisTokenVisitor<T> visitor) {
//     return tokens.map(token -> token.accept(visitor));
//   }
// }
// 
// Path: src/main/java/com/github/tonivade/resp/protocol/RedisTokenType.java
// public enum RedisTokenType {
//   STATUS,
//   INTEGER,
//   STRING,
//   ARRAY,
//   ERROR,
//   UNKNOWN
// }


import static com.github.tonivade.resp.protocol.RedisToken.array;
import static com.github.tonivade.resp.protocol.RedisToken.status;
import static com.github.tonivade.resp.protocol.RedisToken.string;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import com.github.tonivade.resp.protocol.RedisToken;
import com.github.tonivade.resp.protocol.RedisTokenType;
    ArgumentCaptor<RedisToken> captor = ArgumentCaptor.forClass(RedisToken.class);

    verify(callback, timeout(TIMEOUT)).onMessage(captor.capture());

    RedisToken token = captor.getValue();
    assertThat(token.getType(), equalTo(RedisTokenType.STRING));
  }

  private String readBigFile() {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 10000; i++) {
      sb.append("lkjsdfkjaskjflskjf");
    }
    return sb.toString();
  }

  @Test
  public void onClientDisconnect() {
    client.start();
    verify(callback, timeout(TIMEOUT)).onConnect();

    client.stop();
    verify(callback, timeout(TIMEOUT)).onDisconnect();
  }

  @Test
  public void requireHostNonNull() {
    assertThrows(IllegalArgumentException.class, () -> new RespClient(null, 0, callback));
  }

// Path: src/main/java/com/github/tonivade/resp/protocol/RedisToken.java
// static RedisToken array(RedisToken... redisTokens) {
//   return new ArrayRedisToken(ImmutableList.of(redisTokens));
// }
// 
// Path: src/main/java/com/github/tonivade/resp/protocol/RedisToken.java
// static RedisToken status(String str) {
//   return new StatusRedisToken(str);
// }
// 
// Path: src/main/java/com/github/tonivade/resp/protocol/RedisToken.java
// static RedisToken string(SafeString str) {
//   return new StringRedisToken(str);
// }
// 
// Path: src/main/java/com/github/tonivade/resp/protocol/RedisToken.java
// public interface RedisToken {
//   RedisToken NULL_STRING = string((SafeString) null);
//   RedisToken RESPONSE_OK = status("OK");
// 
//   RedisTokenType getType();
// 
//   <T> T accept(RedisTokenVisitor<T> visitor);
// 
//   static RedisToken nullString() {
//     return NULL_STRING;
//   }
// 
//   static RedisToken responseOk() {
//     return RESPONSE_OK;
//   }
// 
//   static RedisToken string(SafeString str) {
//     return new StringRedisToken(str);
//   }
// 
//   static RedisToken string(String str) {
//     return new StringRedisToken(safeString(str));
//   }
// 
//   static RedisToken status(String str) {
//     return new StatusRedisToken(str);
//   }
// 
//   static RedisToken integer(boolean b) {
//     return new IntegerRedisToken(b ? 1 : 0);
//   }
// 
//   static RedisToken integer(int i) {
//     return new IntegerRedisToken(i);
//   }
// 
//   static RedisToken error(String str) {
//     return new ErrorRedisToken(str);
//   }
// 
//   static RedisToken array(RedisToken... redisTokens) {
//     return new ArrayRedisToken(ImmutableList.of(redisTokens));
//   }
// 
//   static RedisToken array(Collection<RedisToken> redisTokens) {
//     return new ArrayRedisToken(ImmutableList.from(redisTokens));
//   }
// 
//   static RedisToken array(Sequence<RedisToken> redisTokens) {
//     return new ArrayRedisToken(redisTokens.asArray());
//   }
// 
//   static <T> Stream<T> visit(Stream<RedisToken> tokens, RedisTokenVisitor<T> visitor) {
//     return tokens.map(token -> token.accept(visitor));
//   }
// }
// 
// Path: src/main/java/com/github/tonivade/resp/protocol/RedisTokenType.java
// public enum RedisTokenType {
//   STATUS,
//   INTEGER,
//   STRING,
//   ARRAY,
//   ERROR,
//   UNKNOWN
// }


// Path: src/test/java/com/github/tonivade/resp/RespClientTest.java
import static com.github.tonivade.resp.protocol.RedisToken.array;
import static com.github.tonivade.resp.protocol.RedisToken.status;
import static com.github.tonivade.resp.protocol.RedisToken.string;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import com.github.tonivade.resp.protocol.RedisToken;
import com.github.tonivade.resp.protocol.RedisTokenType;

    ArgumentCaptor<RedisToken> captor = ArgumentCaptor.forClass(RedisToken.class);

    verify(callback, timeout(TIMEOUT)).onMessage(captor.capture());

    RedisToken token = captor.getValue();
    assertThat(token.getType(), equalTo(RedisTokenType.STRING));
  }

  private String readBigFile() {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 10000; i++) {
      sb.append("lkjsdfkjaskjflskjf");
    }
    return sb.toString();
  }

  @Test
  public void onClientDisconnect() {
    client.start();
    verify(callback, timeout(TIMEOUT)).onConnect();

    client.stop();
    verify(callback, timeout(TIMEOUT)).onDisconnect();
  }

  @Test
  public void requireHostNonNull() {
    assertThrows(IllegalArgumentException.class, () -> new RespClient(null, 0, callback));
  }

  @Test