├── README.md ├── example ├── build.hxml └── src │ ├── Api.hx │ ├── Client.hx │ └── Server.hx ├── haxelib.json ├── license.txt ├── org └── msgpack │ ├── Decoder.hx │ ├── Encoder.hx │ ├── MsgPack.hx │ └── rpc │ ├── MsgPackRpcClient.hx │ └── MsgPackRpcServer.hx └── unit-test ├── .munit ├── src ├── ArrayTest.hx ├── BasicTest.hx ├── Int64Test.hx ├── MapTest.hx ├── ObjectTest.hx ├── TestMain.hx └── TestSuite.hx └── unit-test.hxml /README.md: -------------------------------------------------------------------------------- 1 | [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](license.txt) [![Haxelib Version](https://img.shields.io/github/release/aaulia/msgpack-haxe.svg?style=flat&label=haxelib)](http://lib.haxe.org/p/msgpack-haxe) 2 | 3 | msgpack-haxe 4 | ============ 5 | 6 | MessagePack (http://msgpack.org) serialization library for Haxe 7 | 8 | How to install: 9 | ------------- 10 | Simply use `haxelib git` to use this github repo or `haxelib install msgpack-haxe` to use the one in the haxelib repository. 11 | 12 | Supported Type: 13 | ------------- 14 | * Null 15 | * Bool 16 | * Int 17 | * Float 18 | * Object 19 | * Bytes 20 | * String 21 | * Array 22 | * IntMap/StringMap 23 | 24 | Example code: 25 | ------------- 26 | ``` haxe 27 | package; 28 | import org.msgpack.MsgPack; 29 | 30 | class Example { 31 | public static function main() { 32 | var i = { a: 1, b: 2, c: "Hello World!" }; 33 | var m = MsgPack.encode(i); 34 | var o = MsgPack.decode(m); 35 | 36 | trace(i); 37 | trace(m.toHex()); 38 | trace(o); 39 | } 40 | } 41 | ``` 42 | -------------------------------------------------------------------------------- /example/build.hxml: -------------------------------------------------------------------------------- 1 | # flash client 2 | -cp src 3 | -main Client 4 | -swf bin/Client.swf 5 | -debug 6 | -swf-version 11 7 | -swf-header 500:400:31:ffffff 8 | --flash-strict 9 | -lib msgpack-haxe 10 | 11 | --next 12 | 13 | # php server 14 | -cp src 15 | -main Server 16 | -php bin/www 17 | -debug 18 | -lib msgpack-haxe 19 | -------------------------------------------------------------------------------- /example/src/Api.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | @:keep class Api { 4 | public function new() { } 5 | public function add(a:Int, b:Int):Int { return a + b; } 6 | } 7 | -------------------------------------------------------------------------------- /example/src/Client.hx: -------------------------------------------------------------------------------- 1 | package; 2 | import haxe.remoting.AsyncProxy; 3 | import org.msgpack.rpc.MsgPackRpcClient; 4 | 5 | class ApiProxy extends AsyncProxy {} 6 | class Client { 7 | static public function main() { 8 | var con = MsgPackRpcClient.connect("http://aaulia/send_raw_binary/", "Api"); 9 | var api = new ApiProxy(con); 10 | api.add(1, 2, function(r) { trace(r); }); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /example/src/Server.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import haxe.remoting.Context; 4 | import org.msgpack.rpc.MsgPackRpcServer; 5 | 6 | class Server { 7 | static public function main() { 8 | var ctx = new Context(); 9 | ctx.addObject("Api", new Api()); // Client Proxy must use Connection. 10 | MsgPackRpcServer.run(ctx); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "msgpack-haxe", 3 | "url": "http://github.com/aaulia/msgpack-haxe", 4 | "license": "MIT", 5 | "tags": ["cross","serialization","msgpack"], 6 | "description": "MessagePack (http://msgpack.org) for HaXe", 7 | "version": "1.15.1", 8 | "releasenote": "Update deprecated Int64 getHigh() and getLow()", 9 | "contributors": ["aaulia", "Type1J", "mcheshkov"], 10 | "dependencies": { } 11 | } 12 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2012 Achmad Aulia Noorhakim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /org/msgpack/Decoder.hx: -------------------------------------------------------------------------------- 1 | package org.msgpack; 2 | 3 | import haxe.Int64; 4 | import haxe.ds.IntMap; 5 | import haxe.ds.StringMap; 6 | import haxe.io.Bytes; 7 | import haxe.io.BytesInput; 8 | import haxe.io.Eof; 9 | 10 | using Reflect; 11 | 12 | enum DecodeOption { 13 | AsMap; 14 | AsObject; 15 | } 16 | 17 | private class Pair { 18 | 19 | public var k (default, null) : Dynamic; 20 | public var v (default, null) : Dynamic; 21 | 22 | public function new(k, v) 23 | { 24 | this.k = k; 25 | this.v = v; 26 | } 27 | } 28 | 29 | class Decoder { 30 | var o:Dynamic; 31 | 32 | public function new(b:Bytes, option:DecodeOption) { 33 | var i = new BytesInput(b); 34 | i.bigEndian = true; 35 | o = decode(i, option); 36 | } 37 | 38 | function decode(i:BytesInput, option:DecodeOption):Dynamic { 39 | try { 40 | var b = i.readByte(); 41 | switch (b) { 42 | // null 43 | case 0xc0: return null; 44 | 45 | // boolean 46 | case 0xc2: return false; 47 | case 0xc3: return true; 48 | 49 | // binary 50 | case 0xc4: return i.read(i.readByte ()); 51 | case 0xc5: return i.read(i.readUInt16()); 52 | case 0xc6: return i.read(i.readInt32 ()); 53 | 54 | // floating point 55 | case 0xca: return i.readFloat (); 56 | case 0xcb: return i.readDouble(); 57 | 58 | // unsigned int 59 | case 0xcc: return i.readByte (); 60 | case 0xcd: return i.readUInt16(); 61 | case 0xce: return i.readInt32 (); 62 | case 0xcf: throw "UInt64 not supported"; 63 | 64 | // signed int 65 | case 0xd0: return i.readInt8 (); 66 | case 0xd1: return i.readInt16(); 67 | case 0xd2: return i.readInt32(); 68 | case 0xd3: return readInt64(i); 69 | 70 | // string 71 | case 0xd9: return i.readString(i.readByte ()); 72 | case 0xda: return i.readString(i.readUInt16()); 73 | case 0xdb: return i.readString(i.readInt32 ()); 74 | 75 | // array 16, 32 76 | case 0xdc: return readArray(i, i.readUInt16(), option); 77 | case 0xdd: return readArray(i, i.readInt32 (), option); 78 | 79 | // map 16, 32 80 | case 0xde: return readMap(i, i.readUInt16(), option); 81 | case 0xdf: return readMap(i, i.readInt32 (), option); 82 | 83 | default : { 84 | if (b < 0x80) { return b; } else // positive fix num 85 | if (b < 0x90) { return readMap (i, (0xf & b), option); } else // fix map 86 | if (b < 0xa0) { return readArray(i, (0xf & b), option); } else // fix array 87 | if (b < 0xc0) { return i.readString(0x1f & b); } else // fix string 88 | if (b > 0xdf) { return 0xffffff00 | b; } // negative fix num 89 | } 90 | } 91 | } catch (e:Eof) {} 92 | return null; 93 | } 94 | 95 | function readInt64(i:BytesInput){ 96 | var high = i.readInt32(); 97 | var low = i.readInt32(); 98 | return Int64.make(high, low); 99 | } 100 | 101 | function readArray(i:BytesInput, length:Int, option:DecodeOption) { 102 | var a = []; 103 | for(x in 0...length) { 104 | a.push(decode(i, option)); 105 | } 106 | return a; 107 | } 108 | 109 | function readMap(i:BytesInput, length:Int, option:DecodeOption):Dynamic { 110 | switch (option) { 111 | case DecodeOption.AsObject: 112 | var out = {}; 113 | for (n in 0...length) { 114 | var k = decode(i, option); 115 | var v = decode(i, option); 116 | Reflect.setField(out, Std.string(k), v); 117 | } 118 | 119 | return out; 120 | 121 | case DecodeOption.AsMap: 122 | var pairs = []; 123 | for (n in 0...length) { 124 | var k = decode(i, option); 125 | var v = decode(i, option); 126 | pairs.push(new Pair(k, v)); 127 | } 128 | 129 | if (pairs.length == 0) 130 | return new StringMap(); 131 | 132 | switch(Type.typeof(pairs[0].k)) 133 | { 134 | case TInt: 135 | var out = new IntMap(); 136 | for (p in pairs){ 137 | switch(Type.typeof(p.k)){ 138 | case TInt: 139 | default: 140 | throw "Error: Mixed key type when decoding IntMap"; 141 | } 142 | 143 | if (out.exists(p.k)) 144 | throw 'Error: Duplicate keys found => ${p.k}'; 145 | 146 | out.set(p.k, p.v); 147 | } 148 | 149 | return out; 150 | 151 | case TClass(c) if (Type.getClassName(c) == "String"): 152 | var out = new StringMap(); 153 | for (p in pairs){ 154 | switch(Type.typeof(p.k)){ 155 | case TClass(c) if (Type.getClassName(c) == "String"): 156 | default: 157 | throw "Error: Mixed key type when decoding StringMap"; 158 | } 159 | 160 | if (out.exists(p.k)) 161 | throw 'Error: Duplicate keys found => ${p.k}'; 162 | 163 | out.set(p.k, p.v); 164 | } 165 | 166 | return out; 167 | 168 | default: 169 | throw "Error: Unsupported key Type"; 170 | } 171 | } 172 | 173 | throw "Should not get here"; 174 | } 175 | 176 | public inline function getResult() { 177 | return o; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /org/msgpack/Encoder.hx: -------------------------------------------------------------------------------- 1 | package org.msgpack; 2 | 3 | import haxe.Int64; 4 | import haxe.io.Bytes; 5 | import haxe.io.BytesOutput; 6 | 7 | using Reflect; 8 | 9 | 10 | class Encoder { 11 | 12 | static private inline var FLOAT_SINGLE_MIN:Float = 1.40129846432481707e-45; 13 | static private inline var FLOAT_SINGLE_MAX:Float = 3.40282346638528860e+38; 14 | 15 | static private inline var FLOAT_DOUBLE_MIN:Float = 4.94065645841246544e-324; 16 | static private inline var FLOAT_DOUBLE_MAX:Float = 1.79769313486231570e+308; 17 | 18 | var o:BytesOutput; 19 | 20 | public function new(d:Dynamic) { 21 | o = new BytesOutput(); 22 | o.bigEndian = true; 23 | 24 | encode(d); 25 | } 26 | 27 | function encode(d:Dynamic) { 28 | switch (Type.typeof(d)) { 29 | case TNull : o.writeByte(0xc0); 30 | case TBool : o.writeByte(d ? 0xc3 : 0xc2); 31 | case TInt : writeInt(d); 32 | case TFloat : writeFloat(d); 33 | 34 | case TClass(c): 35 | switch (Type.getClassName(c)) { 36 | case "haxe._Int64.___Int64" : writeInt64(d); 37 | case "haxe.io.Bytes" : writeBinary(d); 38 | case "String" : writeString(d); 39 | case "Array" : writeArray (d); 40 | case "haxe.ds.IntMap" | "haxe.ds.StringMap" | "haxe.ds.UnsafeStringMap" : 41 | writeMap(d); 42 | default: throw 'Error: ${Type.getClassName(c)} not supported'; 43 | } 44 | 45 | case TObject : writeObject(d); 46 | case TEnum(e) : throw "Error: Enum not supported"; 47 | case TFunction: throw "Error: Function not supported"; 48 | case TUnknown : throw "Error: Unknown Data Type"; 49 | } 50 | } 51 | 52 | inline function writeInt64(d:Int64) { 53 | o.writeByte(0xd3); 54 | o.writeInt32(d.high); 55 | o.writeInt32(d.low); 56 | } 57 | 58 | inline function writeInt(d:Int) { 59 | if (d < -(1 << 5)) { 60 | // less than negative fixnum ? 61 | if (d < -(1 << 15)) { 62 | // signed int 32 63 | o.writeByte(0xd2); 64 | o.writeInt32(d); 65 | } else 66 | if (d < -(1 << 7)) { 67 | // signed int 16 68 | o.writeByte(0xd1); 69 | o.writeInt16(d); 70 | } else { 71 | // signed int 8 72 | o.writeByte(0xd0); 73 | o.writeInt8(d); 74 | } 75 | } else 76 | if (d < (1 << 7)) { 77 | // negative fixnum < d < positive fixnum [fixnum] 78 | o.writeByte(d & 0x000000ff); 79 | } else { 80 | // unsigned land 81 | if (d < (1 << 8)) { 82 | // unsigned int 8 83 | o.writeByte(0xcc); 84 | o.writeByte(d); 85 | } else 86 | if (d < (1 << 16)) { 87 | // unsigned int 16 88 | o.writeByte(0xcd); 89 | o.writeUInt16(d); 90 | } else { 91 | // unsigned int 32 92 | // TODO: HaXe writeUInt32 ? 93 | o.writeByte(0xce); 94 | o.writeInt32(d); 95 | } 96 | } 97 | } 98 | 99 | inline function writeFloat(d:Float) { 100 | var a = Math.abs(d); 101 | if (a > FLOAT_SINGLE_MIN && a < FLOAT_SINGLE_MAX) { 102 | // Single Precision Floating 103 | o.writeByte(0xca); 104 | o.writeFloat(d); 105 | } else { 106 | // Double Precision Floating 107 | o.writeByte(0xcb); 108 | o.writeDouble(d); 109 | } 110 | } 111 | 112 | inline function writeBinary(b:Bytes) { 113 | var length = b.length; 114 | if (length < 0x100) { 115 | // binary 8 116 | o.writeByte(0xc4); 117 | o.writeByte(length); 118 | } else 119 | if (length < 0x10000) { 120 | // binary 16 121 | o.writeByte(0xc5); 122 | o.writeUInt16(length); 123 | } else { 124 | // binary 32 125 | o.writeByte(0xc6); 126 | o.writeInt32(length); 127 | } 128 | o.write(b); 129 | } 130 | 131 | inline function writeString(b:String) { 132 | var length = b.length; 133 | if (length < 0x20) { 134 | // fix string 135 | o.writeByte(0xa0 | length); 136 | } else 137 | if (length < 0x100) { 138 | // string 8 139 | o.writeByte(0xd9); 140 | o.writeByte(length); 141 | } else 142 | if (length < 0x10000) { 143 | // string 16 144 | o.writeByte(0xda); 145 | o.writeUInt16(length); 146 | } else { 147 | // string 32 148 | o.writeByte(0xdb); 149 | o.writeInt32(length); 150 | } 151 | o.writeString(b); 152 | } 153 | 154 | inline function writeArray(d:Array) { 155 | var length = d.length; 156 | if (length < 0x10) { 157 | // fix array 158 | o.writeByte(0x90 | length); 159 | } else 160 | if (length < 0x10000) { 161 | // array 16 162 | o.writeByte(0xdc); 163 | o.writeUInt16(length); 164 | } else { 165 | // array 32 166 | o.writeByte(0xdd); 167 | o.writeInt32(length); 168 | } 169 | 170 | for (e in d) { 171 | encode(e); 172 | } 173 | } 174 | 175 | inline function writeMapLength(length:Int) { 176 | if (length < 0x10) { 177 | // fix map 178 | o.writeByte(0x80 | length); 179 | } else 180 | if (length < 0x10000) { 181 | // map 16 182 | o.writeByte(0xde); 183 | o.writeUInt16(length); 184 | } else { 185 | // map 32 186 | o.writeByte(0xdf); 187 | o.writeInt32(length); 188 | } 189 | } 190 | 191 | inline function writeMap(d:Map) { 192 | 193 | var length = 0; 194 | for (k in d.keys()) 195 | length++; 196 | 197 | writeMapLength(length); 198 | for (k in d.keys()) { 199 | encode(k); 200 | encode(d.get(k)); 201 | } 202 | } 203 | 204 | inline function writeObject(d:Dynamic) { 205 | var f = d.fields(); 206 | 207 | writeMapLength(Lambda.count(f)); 208 | for (k in f) { 209 | encode(k); 210 | encode(d.field(k)); 211 | } 212 | } 213 | 214 | public inline function getBytes():Bytes { 215 | return o.getBytes(); 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /org/msgpack/MsgPack.hx: -------------------------------------------------------------------------------- 1 | package org.msgpack; 2 | 3 | import haxe.io.Bytes; 4 | import org.msgpack.Decoder.DecodeOption; 5 | 6 | class MsgPack { 7 | 8 | public static inline function encode(d:Dynamic):Bytes { 9 | return new Encoder(d).getBytes(); 10 | } 11 | 12 | public static inline function decode(b:Bytes, ?option:DecodeOption):Dynamic { 13 | if (option == null) 14 | option = DecodeOption.AsObject; 15 | 16 | return new Decoder(b, option).getResult(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /org/msgpack/rpc/MsgPackRpcClient.hx: -------------------------------------------------------------------------------- 1 | package org.msgpack.rpc; 2 | 3 | #if !flash9 4 | #error "Not implemented for this target platform, flash9 only" 5 | #end 6 | 7 | import flash.net.URLLoader; 8 | import flash.net.URLRequest; 9 | import flash.net.URLLoaderDataFormat; 10 | import flash.net.URLRequestMethod; 11 | 12 | import flash.events.HTTPStatusEvent; 13 | import flash.events.IOErrorEvent; 14 | import flash.events.Event; 15 | import flash.events.SecurityErrorEvent; 16 | 17 | import haxe.remoting.AsyncConnection; 18 | import haxe.io.Bytes; 19 | import haxe.Timer; 20 | 21 | import org.msgpack.MsgPack; 22 | 23 | 24 | class MsgPackRpcClient implements AsyncConnection implements Dynamic { 25 | 26 | var data:{ url:String, error:Dynamic->Void }; 27 | var path:Array; 28 | var fnCb:ArrayVoid>; 29 | 30 | function new(data, path) { 31 | this.data = data; 32 | this.path = path; 33 | this.fnCb = []; 34 | } 35 | 36 | public function resolve(name):AsyncConnection { 37 | var mpc = new MsgPackRpcClient(this.data, this.path.copy()); 38 | mpc.path.push(name); 39 | return mpc; 40 | } 41 | 42 | public function setErrorHandler(onError:Dynamic->Void):Void { 43 | this.data.error = onError; 44 | } 45 | 46 | public function call(params:Array, ?onResult:Dynamic->Void):Void { 47 | 48 | var req = new URLRequest(this.data.url); 49 | req.contentType = "application/octet-stream"; 50 | req.method = URLRequestMethod.POST; 51 | 52 | // 0. msgid (0 = request) 53 | // 1. stamp, int32 54 | // 2. path, string 55 | // 3. params, array 56 | var data:Array = [ 0, Std.int(Timer.stamp()), this.path.join("."), params ]; 57 | req.data = MsgPack.encode(data).getData(); 58 | 59 | fnCb[data[1]] = onResult; 60 | 61 | var ldr = new URLLoader(); 62 | ldr.dataFormat = URLLoaderDataFormat.BINARY; 63 | 64 | ldr.addEventListener(Event.COMPLETE, function(e:Event) { 65 | 66 | // 0. msgid (1 = response) 67 | // 1. stamp, int32 68 | // 2. error, dynamic 69 | // 3. result, dynamic 70 | var res:Array = MsgPack.decode(Bytes.ofData(ldr.data)); 71 | if (res[0] != 1 || res[2] != null) { 72 | if (this.data.error != null) { 73 | this.data.error({ error: "Invalid/error response", data: res }); 74 | } 75 | } 76 | 77 | if (fnCb[res[1]] != null) { 78 | var fnResult = fnCb[res[1]]; 79 | fnCb.splice(res[1], 1); 80 | fnResult(res[3]); 81 | } 82 | }); 83 | 84 | ldr.addEventListener(HTTPStatusEvent.HTTP_STATUS, function(e:HTTPStatusEvent) { 85 | if (e.status >= 400) { 86 | // Error HTTP Status code 87 | if (this.data.error != null) { 88 | this.data.error(e); 89 | } 90 | } 91 | }); 92 | 93 | ldr.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent) { 94 | if (this.data.error != null) { 95 | this.data.error(e); 96 | } 97 | }); 98 | 99 | ldr.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function(e:SecurityErrorEvent) { 100 | if (this.data.error != null) { 101 | this.data.error(e); 102 | } 103 | }); 104 | 105 | ldr.load(req); 106 | 107 | } 108 | 109 | public static function connect(url:String, name:String = ""):AsyncConnection { 110 | var mpc:AsyncConnection = new MsgPackRpcClient({ url: url, error: function(d) throw d }, []); 111 | return if (name != "") { 112 | var path = name.split("."); 113 | for (p in path) { 114 | mpc = mpc.resolve(p); 115 | } 116 | mpc; 117 | } else { 118 | mpc; 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /org/msgpack/rpc/MsgPackRpcServer.hx: -------------------------------------------------------------------------------- 1 | package org.msgpack.rpc; 2 | 3 | #if !php 4 | #error "Not implemented for this target platform, php only" 5 | #end 6 | 7 | import haxe.remoting.Context; 8 | import org.msgpack.MsgPack; 9 | import php.Web; 10 | import sys.io.File; 11 | 12 | class MsgPackRpcServer { 13 | public static function run(ctx:Context) { 14 | if (Web.getMethod() != "POST") { 15 | Web.setReturnCode(501); 16 | return; 17 | } 18 | 19 | var inp = File.read("php://input", true); 20 | inp.bigEndian = true; 21 | var msg = MsgPack.decode(inp.readAll()); 22 | 23 | if (msg == null || msg[0] > 0) { 24 | Web.setReturnCode(501); 25 | return; 26 | } 27 | 28 | var res = [ 1, msg[1], null, ctx.call(cast(msg[2]).split("."), cast(msg[3])) ]; 29 | var out = File.write("php://output", true); 30 | out.bigEndian = true; 31 | out.write(MsgPack.encode(res)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /unit-test/.munit: -------------------------------------------------------------------------------- 1 | version=2.1.0 2 | src=src 3 | bin=build 4 | report=report 5 | hxml=unit-test.hxml 6 | classPaths=../ 7 | -------------------------------------------------------------------------------- /unit-test/src/ArrayTest.hx: -------------------------------------------------------------------------------- 1 | package ; 2 | 3 | import massive.munit.util.Timer; 4 | import massive.munit.Assert; 5 | import massive.munit.async.AsyncFactory; 6 | import org.msgpack.MsgPack; 7 | 8 | 9 | class ArrayTest 10 | { 11 | 12 | 13 | public function new() 14 | { 15 | 16 | } 17 | 18 | @BeforeClass 19 | public function beforeClass():Void 20 | { 21 | } 22 | 23 | @AfterClass 24 | public function afterClass():Void 25 | { 26 | } 27 | 28 | @Before 29 | public function setup():Void 30 | { 31 | } 32 | 33 | @After 34 | public function tearDown():Void 35 | { 36 | } 37 | 38 | @Test 39 | public function testExample():Void 40 | { 41 | var a = [ 3, 2, 1, 7, 8, 9 ]; 42 | var e = MsgPack.encode(a); 43 | var d = MsgPack.decode(e); 44 | 45 | Assert.isType(d, Array); 46 | Assert.isTrue(Lambda.fold(d, function(v, b) { 47 | return b && a[Lambda.indexOf(d, v)] == v; 48 | }, true)); 49 | } 50 | } -------------------------------------------------------------------------------- /unit-test/src/BasicTest.hx: -------------------------------------------------------------------------------- 1 | package ; 2 | 3 | import haxe.io.Bytes; 4 | import massive.munit.util.Timer; 5 | import massive.munit.Assert; 6 | import massive.munit.async.AsyncFactory; 7 | import org.msgpack.MsgPack; 8 | 9 | 10 | class BasicTest 11 | { 12 | 13 | 14 | public function new() 15 | { 16 | 17 | } 18 | 19 | @BeforeClass 20 | public function beforeClass():Void 21 | { 22 | } 23 | 24 | @AfterClass 25 | public function afterClass():Void 26 | { 27 | } 28 | 29 | @Before 30 | public function setup():Void 31 | { 32 | } 33 | 34 | @After 35 | public function tearDown():Void 36 | { 37 | } 38 | 39 | @Test 40 | public function testExample():Void 41 | { 42 | Assert.isNull(doTest(null)); 43 | Assert.isType(doTest(true), Bool); 44 | Assert.isType(doTest(1000), Int); 45 | Assert.isType(doTest(1.01), Float); 46 | Assert.isType(doTest("ab"), String); 47 | Assert.isType(doTest(Bytes.ofString("ab")), Bytes); 48 | 49 | Assert.areEqual(doTest(null), null); 50 | Assert.isTrue(doTest(true)); 51 | Assert.areEqual(doTest(1000), 1000); 52 | Assert.isTrue(Math.abs(1.01 - cast doTest(1.01)) <= 0.00000001); 53 | Assert.areEqual(doTest("ab"), "ab"); 54 | 55 | var d = cast(doTest(Bytes.ofString("ab")), Bytes); 56 | var a = Bytes.ofString("ab"); 57 | 58 | Assert.isTrue((d.length == a.length) && (d.toString() == a.toString())); 59 | } 60 | 61 | function doTest(a:T) 62 | { 63 | var e = MsgPack.encode(a); 64 | var d = MsgPack.decode(e); 65 | 66 | return d; 67 | } 68 | } -------------------------------------------------------------------------------- /unit-test/src/Int64Test.hx: -------------------------------------------------------------------------------- 1 | package ; 2 | 3 | import haxe.Int64; 4 | import massive.munit.Assert; 5 | import org.msgpack.MsgPack; 6 | 7 | class Int64Test 8 | { 9 | 10 | public function new() 11 | { 12 | 13 | } 14 | 15 | @BeforeClass 16 | public function beforeClass():Void 17 | { 18 | } 19 | 20 | @AfterClass 21 | public function afterClass():Void 22 | { 23 | } 24 | 25 | @Before 26 | public function setup():Void 27 | { 28 | } 29 | 30 | @After 31 | public function tearDown():Void 32 | { 33 | } 34 | 35 | @Test 36 | public function testExample():Void 37 | { 38 | var e = MsgPack.encode(Int64.make(1,2)); 39 | var d = MsgPack.decode(e); 40 | 41 | Assert.isTrue(Std.is(d, Int64)); 42 | Assert.isTrue(Int64.getHigh(d) == 1); 43 | Assert.isTrue(Int64.getLow(d) == 2); 44 | } 45 | } -------------------------------------------------------------------------------- /unit-test/src/MapTest.hx: -------------------------------------------------------------------------------- 1 | package ; 2 | 3 | import haxe.ds.IntMap; 4 | import haxe.ds.StringMap; 5 | import massive.munit.util.Timer; 6 | import massive.munit.Assert; 7 | import massive.munit.async.AsyncFactory; 8 | import org.msgpack.Decoder.DecodeOption.AsMap; 9 | import org.msgpack.MsgPack; 10 | 11 | 12 | class MapTest 13 | { 14 | 15 | 16 | public function new() 17 | { 18 | 19 | } 20 | 21 | @BeforeClass 22 | public function beforeClass():Void 23 | { 24 | } 25 | 26 | @AfterClass 27 | public function afterClass():Void 28 | { 29 | } 30 | 31 | @Before 32 | public function setup():Void 33 | { 34 | } 35 | 36 | @After 37 | public function tearDown():Void 38 | { 39 | } 40 | 41 | @Test 42 | public function testExample():Void 43 | { 44 | var im = new IntMap(); 45 | im.set(1, "one"); 46 | im.set(3, "Three"); 47 | im.set(9, "Nine"); 48 | 49 | var e = MsgPack.encode(im); 50 | var d = MsgPack.decode(e, AsMap); 51 | 52 | Assert.isType(d, IntMap); 53 | 54 | var ni = cast(d, IntMap); 55 | for (k in im.keys()) 56 | Assert.isTrue(ni.exists(k) && ni.get(k) == im.get(k)); 57 | 58 | 59 | var sm = new StringMap(); 60 | sm.set("one", 1); 61 | sm.set("Three", 3); 62 | sm.set("Nine", 9); 63 | 64 | e = MsgPack.encode(sm); 65 | d = MsgPack.decode(e, AsMap); 66 | 67 | Assert.isType(d, StringMap); 68 | 69 | var ns = cast(d, StringMap); 70 | for (k in sm.keys()) 71 | Assert.isTrue(ns.exists(k) && ns.get(k) == sm.get(k)); 72 | 73 | } 74 | } -------------------------------------------------------------------------------- /unit-test/src/ObjectTest.hx: -------------------------------------------------------------------------------- 1 | package ; 2 | 3 | import massive.munit.util.Timer; 4 | import massive.munit.Assert; 5 | import massive.munit.async.AsyncFactory; 6 | import org.msgpack.Decoder.DecodeOption.AsObject; 7 | import org.msgpack.MsgPack; 8 | 9 | 10 | class ObjectTest 11 | { 12 | 13 | 14 | public function new() 15 | { 16 | 17 | } 18 | 19 | @BeforeClass 20 | public function beforeClass():Void 21 | { 22 | } 23 | 24 | @AfterClass 25 | public function afterClass():Void 26 | { 27 | } 28 | 29 | @Before 30 | public function setup():Void 31 | { 32 | } 33 | 34 | @After 35 | public function tearDown():Void 36 | { 37 | } 38 | 39 | @Test 40 | public function testExample():Void 41 | { 42 | var e = MsgPack.encode({ a: 10, b: "abc"}); 43 | var d = MsgPack.decode(e, AsObject); 44 | 45 | Assert.isTrue(Reflect.hasField(d, "a") 46 | && Reflect.hasField(d, "b") 47 | && Reflect.field(d, "a") == 10 48 | && Reflect.field(d, "b") == "abc"); 49 | } 50 | } -------------------------------------------------------------------------------- /unit-test/src/TestMain.hx: -------------------------------------------------------------------------------- 1 | import massive.munit.client.PrintClient; 2 | import massive.munit.client.RichPrintClient; 3 | import massive.munit.client.HTTPClient; 4 | import massive.munit.client.JUnitReportClient; 5 | import massive.munit.client.SummaryReportClient; 6 | import massive.munit.TestRunner; 7 | 8 | #if js 9 | import js.Lib; 10 | #end 11 | 12 | /** 13 | * Auto generated Test Application. 14 | * Refer to munit command line tool for more information (haxelib run munit) 15 | */ 16 | class TestMain 17 | { 18 | static function main(){ new TestMain(); } 19 | 20 | public function new() 21 | { 22 | var suites = new Array>(); 23 | suites.push(TestSuite); 24 | 25 | #if MCOVER 26 | var client = new mcover.coverage.munit.client.MCoverPrintClient(); 27 | var httpClient = new HTTPClient(new mcover.coverage.munit.client.MCoverSummaryReportClient()); 28 | #else 29 | var client = new RichPrintClient(); 30 | var httpClient = new HTTPClient(new SummaryReportClient()); 31 | #end 32 | 33 | var runner:TestRunner = new TestRunner(client); 34 | runner.addResultClient(httpClient); 35 | //runner.addResultClient(new HTTPClient(new JUnitReportClient())); 36 | 37 | runner.completionHandler = completionHandler; 38 | runner.run(suites); 39 | } 40 | 41 | /* 42 | updates the background color and closes the current browser 43 | for flash and html targets (useful for continous integration servers) 44 | */ 45 | function completionHandler(successful:Bool):Void 46 | { 47 | try 48 | { 49 | #if flash 50 | flash.external.ExternalInterface.call("testResult", successful); 51 | #elseif js 52 | js.Lib.eval("testResult(" + successful + ");"); 53 | #elseif sys 54 | Sys.exit(0); 55 | #end 56 | } 57 | // if run from outside browser can get error which we can ignore 58 | catch (e:Dynamic) 59 | { 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /unit-test/src/TestSuite.hx: -------------------------------------------------------------------------------- 1 | import massive.munit.TestSuite; 2 | 3 | import MapTest; 4 | import BasicTest; 5 | import ArrayTest; 6 | import ObjectTest; 7 | 8 | /** 9 | * Auto generated Test Suite for MassiveUnit. 10 | * Refer to munit command line tool for more information (haxelib run munit) 11 | */ 12 | 13 | class TestSuite extends massive.munit.TestSuite 14 | { 15 | 16 | public function new() 17 | { 18 | super(); 19 | 20 | add(MapTest); 21 | add(BasicTest); 22 | add(ArrayTest); 23 | add(ObjectTest); 24 | add(Int64Test); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /unit-test/unit-test.hxml: -------------------------------------------------------------------------------- 1 | ## Flash 9+ 2 | -main TestMain 3 | -lib munit 4 | -lib hamcrest 5 | -cp ../ 6 | 7 | -cp src 8 | -swf-version 11 9 | -swf build/as3_test.swf 10 | 11 | --next 12 | 13 | ## Flash 8 14 | -main TestMain 15 | -lib munit 16 | -lib hamcrest 17 | -cp ../ 18 | 19 | -cp src 20 | -swf-version 8 21 | -swf build/as2_test.swf 22 | 23 | --next 24 | 25 | ## JavaScript 26 | -main TestMain 27 | -lib munit 28 | -lib hamcrest 29 | -cp ../ 30 | 31 | -cp src 32 | -js build/js_test.js 33 | 34 | --next 35 | 36 | ## Neko 37 | -main TestMain 38 | -lib munit 39 | -lib hamcrest 40 | -cp ../ 41 | 42 | -cp src 43 | -neko build/neko_test.n 44 | 45 | --next 46 | 47 | ## CPP 48 | -main TestMain 49 | -lib munit 50 | -lib hamcrest 51 | -cp ../ 52 | 53 | -cp src 54 | #-D HXCPP_M64 55 | -cpp build/cpp_test 56 | 57 | 58 | --------------------------------------------------------------------------------