if (TestEditorExtends) { largeModule('Serialize'); function match (obj, expect, info) { deepEqual(JSON.parse(EditorExtends.serialize(obj)), expect, info); //deepEqual(EditorExtends.serialize(obj, {stringify: false}), expect, info); } test('basic test', function() { match({}, {}, 'smoke test1'); match([], [[]], 'smoke test2'); var BaseAsset = function () { this.inheritProp = 321; }; var MyAsset = (function () { var _super = BaseAsset; function MyAsset () { _super.call(this); this.emptyArray = []; this.array = [1, '2', {a:3}, [4, [5]], true]; this.string = 'unknown'; this.number = 1; this.boolean = true; this.emptyObj = {}; this.obj = {}; } cc.js.extend(MyAsset, _super); cc.js.setClassName('MyAsset', MyAsset); // should not serialize ---------------------------- MyAsset.staticFunc = function () { }; MyAsset.staticProp = cc.Enum({ UseBest: -1, Ascending: -1, Descending: -1 }); MyAsset.prototype.protoFunc = function () { }; MyAsset.prototype.protoProp = 123; // ------------------------------------------------- return MyAsset; })(); var asset = new MyAsset(); asset.dynamicProp = false; var expect = { __type__: 'MyAsset', emptyArray: [], array: [1, '2', {a:3}, [4, [5]], true], string: 'unknown', number: 1, boolean: true, emptyObj: {}, obj: {}, dynamicProp: false, inheritProp: 321 }; match(asset, expect, 'type test'); match(asset, expect, 'test re-serialize again'); cc.js.unregisterClass(MyAsset); }); test('nil', function () { var obj = { 'null': null, 'undefined': undefined, }; var expect = { 'null': null }; match(obj, expect); }); test('test inherited CCClass', function() { var MyAsset = cc.Class({ name: 'MyAsset', extends: cc.Asset, ctor: function () { this.array = [1, '2', {a: 3}, [4, [5]], true]; }, properties: { emptyArray: [], array: null, string: 'unknown', number: 1, boolean: true, emptyObj: { default: {} }, obj: { default: {} } } }); // should not serialize ---------------------------- MyAsset.staticFunc = function () { }; MyAsset.staticProp = cc.Enum({ UseBest: -1, Ascending: -1, Descending: -1 }); MyAsset.prototype.protoFunc = function () { }; MyAsset.prototype.protoProp = 123; // ------------------------------------------------- var asset = new MyAsset(); asset.dynamicProp = false; // should not serialize asset._objFlags |= cc.Object.Flags.Destroying; // should not serialize var expect = { __type__: 'MyAsset', _name: '', _objFlags: 0, _native: "", emptyArray: [], array: [1, '2', {a:3}, [4, [5]], true], string: 'unknown', number: 1, boolean: true, emptyObj: {}, obj: {} }; match(asset, expect, 'test'); cc.js.unregisterClass(MyAsset); }); test('test CCClass', function () { var Sprite = cc.Class({ name: 'Sprite', ctor: function () { this.image = 'sprite.png'; }, properties: { size: new cc.Vec2(128, 128) } }); var sprite = new Sprite(); var actual = JSON.parse(EditorExtends.serialize(sprite)); strictEqual(actual.image, undefined, 'should not serialize variable which not defined by property'); var expected = { __type__: 'Sprite', size: { __type__: "cc.Vec2", x: 128, y: 128 } }; deepEqual(actual, expected, 'can serialize'); cc.js.unregisterClass(Sprite); }); test('CCClass which inherited from CCObject', function () { var type = cc.Class({ name: 'cc.MyType', extends: CCObject }); var obj = new type(); obj.name = '阿加西'; var json = JSON.parse(EditorExtends.serialize(obj)); var expected = { "__type__": "cc.MyType", "_name": "阿加西", "_objFlags": 0 }; deepEqual(json, expected, 'can serialize CCObject.name'); cc.js.unregisterClass(type); }); test('test circular reference', function () { function MyAsset () { this.array1 = [1]; this.array2 = [this.array1, 2]; this.array1.push(this.array2); // array1 = [1, array2] // array2 = [array1, 2] this.dict1 = {num: 1}; this.dict2 = {num: 2, other: this.dict1}; this.dict1.other = this.dict2; } var asset = new MyAsset(); var expect = [ { array1: { __id__: 1 }, array2: [ { __id__: 1 }, 2 ], dict1: { __id__: 2 }, dict2: { /*__id__: 4,*/ num:2, other: {__id__: 2} }, }, [ 1, [{ __id__: 1 }, 2] ], // You'll get two copies of array2 { /*__id__: 2,*/ num:1, other: {num:2, other: {__id__: 2}} }, // You'll get two copies of dict2 ]; match(asset, expect, 'arrays and dicts can circular reference each other'); match(asset, expect, 'test re-serialize again'); }); test('test serializable attributes', function () { var Sprite = cc.Class({ name: 'Sprite', properties: { trimThreshold: { default: 2, editorOnly: true }, _isValid: { default: true, serializable: false } } }); var sprite = new Sprite(); var resultInEditor = JSON.parse(EditorExtends.serialize(sprite)); strictEqual(resultInEditor.trimThreshold, 2, 'serialize editor only in editor'); strictEqual(resultInEditor._isValid, undefined, 'should not serialize non-serialized in editor'); cc.js.unregisterClass(Sprite); }); test('fast defined property', function () { function Vec3 (x, y, z) { this.data = [x, y, z]; } cc.Class.fastDefine('Vec3', Vec3, { x: 0, y: 0, z: 0, }); Object.defineProperties(Vec3.prototype, { x: { get: function () { return this.data[0]; }, set: function (value) { this.data[0] = value; }, }, y: { get: function () { return this.data[1]; }, set: function (value) { this.data[1] = value; }, }, z: { get: function () { return this.data[2]; }, set: function (value) { this.data[2] = value; }, } }); var obj = new Vec3(2, 3 ,1); var expected = { __type__: 'Vec3', x: 2, y: 3, z: 1, }; match(obj, expected, 'should be able to serialize'); cc.js.unregisterClass(Vec3); }); test('test asset property', function () { var sprite = new TestSprite(); sprite.texture = new TestTexture(); var uuid = '541020432560'; sprite.texture._uuid = uuid; var result = JSON.parse(EditorExtends.serialize(sprite)); deepEqual(result.texture, {__uuid__: uuid}, 'serialize asset as uuid reference'); }); test('test CCObject reference', function () { var fobj = new cc.Object(); var asset = { ref1: fobj, ref2: fobj }; var expected = [ { "ref1": { "__id__": 1 }, "ref2": { "__id__": 1 } }, { "__type__": "cc.Object", "_objFlags": 0, "_name": "" }, ]; match(asset, expected, 'references should the same'); }); test('main asset', function () { var Scene = cc.Class({ name: "Scene", properties: { entities: [], } }); var Entity = cc.Class({ name: "Entity" }); var scene = new Scene(); scene.entities.push(new Entity()); var expected = [ { "__type__": "Scene", "entities": [ { "__id__": 1 } ] }, { "__type__": "Entity", } ]; match(scene, expected, 'main asset should listed first'); cc.js.unregisterClass(Scene, Entity); }); test('nicify ', function () { var data = [ { "ref1": [1, 2, 3, { "__id__": 1 }, { "a": 1, "b": 2, "c": { "__id__": 2 } }], "ref2": { "__id__": 1 }, "ref3": { "__id__": 3 }, "ref4": { "__id__": 3 }, "ref5": [{ "__id__": 4 }, { "__id__": 4 }] }, { "__type__": "cc.Object", "_name": "test_1", "_objFlags": 0 }, { "__type__": "cc.Object", "_name": "test_2", "_objFlags": 0 }, { "__type__": "cc.Object", "_name": "test_3", "_objFlags": 0 }, { "__type__": "cc.Object", "_name": "test_4", "_objFlags": 0 } ]; var expected = [ { "ref1": [1, 2, 3, { "__id__": 1 }, { "a": 1, "b": 2, "c": { "__type__": "cc.Object", "_name": "test_2", "_objFlags": 0 } }], "ref2": { "__id__": 1 }, "ref3": { "__id__": 2 }, "ref4": { "__id__": 2 }, "ref5": [{ "__id__": 3 }, { "__id__": 3 }] }, { "__type__": "cc.Object", "_name": "test_1", "_objFlags": 0 }, { "__type__": "cc.Object", "_name": "test_3", "_objFlags": 0 }, { "__type__": "cc.Object", "_name": "test_4", "_objFlags": 0 } ]; cc._Test.nicifySerialized(data); deepEqual(data, expected, 'nicify success'); }); test('nicify 1 ', function () { var data = [ { "ref1": { "__id__": 1 } }, { "ref2": { "__id__": 2 }, }, { "ref3": { "__id__": 3 }, }, { "123": 1, }, ]; var expected = [ { "ref1": { "ref2": { "ref3": { "123": 1 } }} }, ]; cc._Test.nicifySerialized(data); deepEqual(data, expected, 'nicify success'); }); test('nicify 2 ', function () { var data = [ { "ref1": { "__id__": 1 } }, { "ref0": { "__id__": 0 }, }, ]; var expected = [ { "ref1": { "ref0": { "__id__": 0 } } }, ]; cc._Test.nicifySerialized(data); deepEqual(data, expected, 'nicify success'); }); test('node array', function () { var Data = cc.Class({ name: 'data', properties: { nodes: { default: [], type: [cc.Node] } } }); var data = new Data(); var node1 = new cc.Node(); var node2 = new cc.Node(); data.nodes = [node1, node2]; var actual = JSON.parse(EditorExtends.serialize(data)); ok(Array.isArray(actual), 'checking'); deepEqual(actual[0], { __type__: 'data', nodes: [ { "__id__": 1 }, { "__id__": 2 } ], }, 'checking'); ok(actual[1].constructor === Object, 'checking'); strictEqual(actual[1].__type__, "cc.Node", 'checking'); ok(actual[2].constructor === Object, 'checking'); strictEqual(actual[2].__type__, "cc.Node", 'checking'); cc.js.unregisterClass(Data); }); test('formerlySerializedAs attribute', function () { var MyAsset = cc.Class({ name: 'MyAsset', properties: { newRefSelf: { default: null, formerlySerializedAs: 'oldRefSelf' }, } }); var asset = new MyAsset(); asset.newRefSelf = asset; var expect = { __type__: 'MyAsset', newRefSelf: { __id__: 0 }, oldRefSelf: { __id__: 0 }, }; match(asset, expect, 'test'); cc.js.unregisterClass(MyAsset); }); }