Commit f4def5ef authored by Him188's avatar Him188

Add tests for Jce

parent c8a68ab5
......@@ -41,8 +41,11 @@ fun ktor(id: String, version: String) = "io.ktor:ktor-$id:$version"
dependencies {
runtimeOnly(files("../mirai-core/build/classes/kotlin/jvm/main")) // IDE bug
runtimeOnly(files("../mirai-core-timpc/build/classes/kotlin/jvm/main")) // IDE bug
implementation(project(":mirai-core-timpc"))
runtimeOnly(files("../mirai-core-qqandroid/build/classes/kotlin/jvm/main")) // IDE bug
implementation(project(":mirai-core-qqandroid"))
// runtimeOnly(files("../mirai-core/build/classes/kotlin/jvm/main")) // classpath is not added correctly by IDE
implementation("org.bouncycastle:bcprov-jdk15on:1.64")
......@@ -70,4 +73,9 @@ dependencies {
implementation(ktor("client-core", ktorVersion))
implementation(ktor("network", ktorVersion))
testImplementation(kotlin("test-annotations-common"))
testImplementation(kotlin("test"))
testImplementation(kotlin("test-junit"))
testImplementation(kotlin("script-runtime"))
}
\ No newline at end of file
package jce.jce;
import java.io.UnsupportedEncodingException;
public class HexUtil {
private static final char[] digits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
public static final byte[] emptybytes = new byte[0];
public static String byte2HexStr(byte var0) {
char var1 = digits[var0 & 15];
var0 = (byte) (var0 >>> 4);
return new String(new char[]{digits[var0 & 15], var1});
}
public static String bytes2HexStr(byte[] var0) {
if (var0 != null && var0.length != 0) {
char[] var3 = new char[var0.length * 2];
for (int var1 = 0; var1 < var0.length; ++var1) {
byte var2 = var0[var1];
var3[var1 * 2 + 1] = digits[var2 & 15];
var2 = (byte) (var2 >>> 4);
var3[var1 * 2 + 0] = digits[var2 & 15];
}
return new String(var3);
} else {
return null;
}
}
public static byte char2Byte(char var0) {
if (var0 >= '0' && var0 <= '9') {
return (byte) (var0 - 48);
} else if (var0 >= 'a' && var0 <= 'f') {
return (byte) (var0 - 97 + 10);
} else {
return var0 >= 'A' && var0 <= 'F' ? (byte) (var0 - 65 + 10) : 0;
}
}
public static byte hexStr2Byte(String var0) {
byte var2 = 0;
byte var1 = var2;
if (var0 != null) {
var1 = var2;
if (var0.length() == 1) {
var1 = char2Byte(var0.charAt(0));
}
}
return var1;
}
public static byte[] hexStr2Bytes(String var0) {
if (var0 != null && !var0.equals("")) {
byte[] var4 = new byte[var0.length() / 2];
for (int var3 = 0; var3 < var4.length; ++var3) {
char var1 = var0.charAt(var3 * 2);
char var2 = var0.charAt(var3 * 2 + 1);
var4[var3] = (byte) (char2Byte(var1) * 16 + char2Byte(var2));
}
return var4;
} else {
return emptybytes;
}
}
public static void main(String[] var0) {
try {
byte[] var2 = "Hello WebSocket World?".getBytes("gbk");
System.out.println(bytes2HexStr(var2));
} catch (UnsupportedEncodingException var1) {
var1.printStackTrace();
}
}
}
package jce.jce;
public class JceDecodeException extends RuntimeException {
public JceDecodeException(String var1) {
super(var1);
}
}
package jce.jce;
public class JceEncodeException extends RuntimeException {
public JceEncodeException(String var1) {
super(var1);
}
}
package jce.jce;
public class JceInputStream$HeadData {
public int tag;
public byte type;
public void clear() {
this.type = 0;
this.tag = 0;
}
}
This diff is collapsed.
This diff is collapsed.
package jce.jce;
import java.io.Serializable;
public abstract class JceStruct implements Serializable {
public static final byte BYTE = 0;
public static final byte DOUBLE = 5;
public static final byte FLOAT = 4;
public static final byte INT = 2;
public static final int JCE_MAX_STRING_LENGTH = 104857600;
public static final byte LIST = 9;
public static final byte LONG = 3;
public static final byte MAP = 8;
public static final byte SHORT = 1;
public static final byte SIMPLE_LIST = 13;
public static final byte STRING1 = 6;
public static final byte STRING4 = 7;
public static final byte STRUCT_BEGIN = 10;
public static final byte STRUCT_END = 11;
public static final byte ZERO_TAG = 12;
public static String toDisplaySimpleString(JceStruct var0) {
if (var0 == null) {
return null;
} else {
StringBuilder var1 = new StringBuilder();
var0.displaySimple(var1, 0);
return var1.toString();
}
}
public boolean containField(String var1) {
return false;
}
public void display(StringBuilder var1, int var2) {
}
public void displaySimple(StringBuilder var1, int var2) {
}
public Object getFieldByName(String var1) {
return null;
}
public JceStruct newInit() {
return null;
}
public abstract void readFrom(JceInputStream var1);
public void recyle() {
}
public void setFieldByName(String var1, Object var2) {
}
public byte[] toByteArray() {
JceOutputStream var1 = new JceOutputStream();
this.writeTo(var1);
return var1.toByteArray();
}
public byte[] toByteArray(String var1) {
JceOutputStream var2 = new JceOutputStream();
var2.setServerEncoding(var1);
this.writeTo(var2);
return var2.toByteArray();
}
public String toString() {
StringBuilder var1 = new StringBuilder();
this.display(var1, 0);
return var1.toString();
}
public abstract void writeTo(JceOutputStream var1);
}
This diff is collapsed.
package jce.jce;
import java.nio.ByteBuffer;
public interface OnIllegalArgumentException {
void onException(IllegalArgumentException var1, ByteBuffer var2, int var3, int var4);
}
package jceTest
import io.ktor.util.InternalAPI
import jce.jce.JceInputStream
import jce.jce.JceOutputStream
import jce.jce.JceStruct
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.readBytes
import net.mamoe.mirai.qqandroid.network.io.JceInput
import net.mamoe.mirai.qqandroid.network.io.JceOutput
import net.mamoe.mirai.qqandroid.network.io.buildJcePacket
import net.mamoe.mirai.utils.io.toUHexString
import org.junit.Test
private infix fun ByteReadPacket.shouldEqualTo(another: ByteArray) {
this.readBytes().let {
check(it.contentEquals(another)) {
"""actual: ${it.toUHexString()}
|required: ${another.toUHexString()}
""".trimMargin()
}
}
}
@UseExperimental(InternalAPI::class)
private fun qqJce(block: JceOutputStream.() -> Unit): ByteArray {
return JceOutputStream().apply(block).toByteArray()
}
internal class JceOutputTest {
@Test
fun writeByte() {
buildJcePacket {
writeByte(1, 1)
writeByte(-128, 2)
} shouldEqualTo qqJce {
write(1.toByte(), 1)
write((-128).toByte(), 2)
}
}
@Test
fun writeDouble() {
buildJcePacket {
writeDouble(1.0, 1)
writeDouble(-128.0, 2)
} shouldEqualTo qqJce {
write(1.toDouble(), 1)
write((-128).toDouble(), 2)
}
}
@Test
fun writeFloat() {
buildJcePacket {
writeFloat(1.0f, 1)
writeFloat(-128.0f, 2)
} shouldEqualTo qqJce {
write(1.toFloat(), 1)
write((-128).toFloat(), 2)
}
}
@Test
fun writeFully() {
buildJcePacket {
writeFully(byteArrayOf(1, 2), 1)
writeFully(byteArrayOf(1, 2), 2)
} shouldEqualTo qqJce {
write(byteArrayOf(1, 2), 1)
write(byteArrayOf(1, 2), 2)
}
}
@Test
fun testWriteFully() {
buildJcePacket {
writeFully(intArrayOf(1, 2), 1)
writeFully(intArrayOf(1, 2), 2)
} shouldEqualTo qqJce {
write(intArrayOf(1, 2), 1)
write(intArrayOf(1, 2), 2)
}
}
@Test
fun testWriteFully1() {
buildJcePacket {
writeFully(shortArrayOf(1, 2), 1)
writeFully(shortArrayOf(1, 2), 2)
} shouldEqualTo qqJce {
write(shortArrayOf(1, 2), 1)
write(shortArrayOf(1, 2), 2)
}
}
@Test
fun testWriteFully2() {
buildJcePacket {
writeFully(booleanArrayOf(true, false), 1)
writeFully(booleanArrayOf(true, false), 2)
} shouldEqualTo qqJce {
write(booleanArrayOf(true, false), 1)
write(booleanArrayOf(true, false), 2)
}
}
@Test
fun testWriteFully3() {
buildJcePacket {
writeFully(longArrayOf(1, 2), 1)
writeFully(longArrayOf(1, 2), 2)
} shouldEqualTo qqJce {
write(longArrayOf(1, 2), 1)
write(longArrayOf(1, 2), 2)
}
}
@Test
fun testWriteFully4() {
buildJcePacket {
writeFully(floatArrayOf(1f, 2f), 1)
writeFully(floatArrayOf(1f, 2f), 2)
} shouldEqualTo qqJce {
write(floatArrayOf(1f, 2f), 1)
write(floatArrayOf(1f, 2f), 2)
}
}
@Test
fun testWriteFully5() {
buildJcePacket {
writeFully(doubleArrayOf(1.0, 2.0), 1)
writeFully(doubleArrayOf(1.0, 2.0), 2)
} shouldEqualTo qqJce {
write(doubleArrayOf(1.0, 2.0), 1)
write(doubleArrayOf(1.0, 2.0), 2)
}
}
@Test
fun testWriteFully6() {
buildJcePacket {
writeFully(arrayOf("123", "哈哈"), 1)
writeFully(arrayOf("123", "哈哈"), 2)
} shouldEqualTo qqJce {
write(arrayOf("123", "哈哈"), 1)
write(arrayOf("123", "哈哈"), 2)
}
}
@Test
fun writeInt() {
buildJcePacket {
writeInt(1, 1)
writeInt(-128, 2)
} shouldEqualTo qqJce {
write(1, 1)
write(-128, 2)
}
}
@Test
fun writeLong() {
buildJcePacket {
writeLong(1, 1)
writeLong(-128, 2)
} shouldEqualTo qqJce {
write(1L, 1)
write(-128L, 2)
}
}
@Test
fun writeShort() {
buildJcePacket {
writeShort(1, 1)
writeShort(-128, 2)
} shouldEqualTo qqJce {
write(1.toShort(), 1)
write((-128).toShort(), 2)
}
}
@Test
fun writeBoolean() {
buildJcePacket {
writeBoolean(true, 1)
writeBoolean(false, 2)
} shouldEqualTo qqJce {
write(true, 1)
write(false, 2)
}
}
@Test
fun writeString() {
buildJcePacket {
writeString("1", 1)
writeString("哈啊", 2)
} shouldEqualTo qqJce {
write("1", 1)
write("哈啊", 2)
}
}
@Test
fun writeMap() {
buildJcePacket {
writeMap(mapOf("" to ""), 1)
writeMap(mapOf("" to 123), 2)
writeMap(mapOf(123.0 to "Hello"), 3)
} shouldEqualTo qqJce {
write(mapOf("" to ""), 1)
write(mapOf("" to 123), 2)
write(mapOf(123.0 to "Hello"), 3)
}
}
@Test
fun writeCollection() {
buildJcePacket {
writeMap(mapOf("" to ""), 1)
writeMap(mapOf("" to 123), 2)
writeMap(mapOf(123.0 to "Hello"), 3)
} shouldEqualTo qqJce {
write(mapOf("" to ""), 1)
write(mapOf("" to 123), 2)
write(mapOf(123.0 to "Hello"), 3)
}
}
data class TestMiraiStruct(
val message: String
) : net.mamoe.mirai.qqandroid.network.io.JceStruct() {
override fun writeTo(builder: JceOutput) {
builder.writeString(message, 0)
}
companion object : Factory<TestMiraiStruct> {
override fun newInstanceFrom(input: JceInput): TestMiraiStruct {
return TestMiraiStruct(input.readString(0))
}
}
}
class TestQQStruct(
private var message: String
) : JceStruct() {
override fun readFrom(var1: JceInputStream) {
message = var1.read("", 0, true)
}
override fun writeTo(var1: JceOutputStream) {
var1.write(message, 0)
}
}
@Test
fun writeJceStruct() {
buildJcePacket {
writeJceStruct(TestMiraiStruct("Hello"), 0)
writeJceStruct(TestMiraiStruct("嗨"), 1)
} shouldEqualTo qqJce {
write(TestQQStruct("Hello"), 0)
write(TestQQStruct("嗨"), 1)
}
}
@Test
fun writeObject() {
buildJcePacket {
writeObject(0.toByte(), 1)
writeObject(0.toShort(), 2)
writeObject(0, 3)
writeObject(0L, 4)
writeObject(0f, 5)
writeObject(0.0, 6)
writeObject("hello", 7)
writeObject(TestMiraiStruct("Hello"), 8)
} shouldEqualTo qqJce {
write(0.toByte(), 1)
write(0.toShort(), 2)
write(0, 3)
write(0L, 4)
write(0f, 5)
write(0.0, 6)
write("hello", 7)
write(TestQQStruct("Hello"), 8)
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment