text: var ttypes = require('./gen-nodejs/JsDeepConstructorTest_types');
  var thrift = require('thrift');
  var test = require('tape');
  
  
  function serializeBinary(data) {
    var buff;
    var transport = new thrift.TBufferedTransport(null, function(msg){
      buff = msg;
    });
    var prot = new thrift.TBinaryProtocol(transport);
    data.write(prot);
    prot.flush();
    return buff;
  
  }
  
  
  function deserializeBinary(serialized, type) {
    var t = new thrift.TFramedTransport(serialized);
    var p = new thrift.TBinaryProtocol(t);
    var data = new type();
    data.read(p);
    return data;
  }
  
  
  function serializeJSON(data) {
    var buff;
    var transport = new thrift.TBufferedTransport(null, function(msg){
      buff = msg;
    });
    var protocol  = new thrift.TJSONProtocol(transport);
    protocol.writeMessageBegin("", 0, 0);
    data.write(protocol);
    protocol.writeMessageEnd();
    protocol.flush();
    return buff;
  }
  
  
  function deserializeJSON(serialized, type) {
    var transport = new thrift.TFramedTransport(serialized);
    var protocol  = new thrift.TJSONProtocol(transport);
    protocol.readMessageBegin();
    var data = new type();
    data.read(protocol);
    protocol.readMessageEnd();
    return data;
  }
  
  
  function createThriftObj() {
  
    return new ttypes.Complex({
  
      struct_field: new ttypes.Simple({value: 'a'}),
  
      struct_list_field: [
        new ttypes.Simple({value: 'b'}),
        new ttypes.Simple({value: 'c'}),
      ],
  
      struct_set_field: [
        new ttypes.Simple({value: 'd'}),
        new ttypes.Simple({value: 'e'}),
      ],
  
      struct_map_field: {
        A: new ttypes.Simple({value: 'f'}),
        B: new ttypes.Simple({value: 'g'})
      },
  
      struct_nested_containers_field: [
        [
          {
            C: [
              new ttypes.Simple({value: 'h'}),
              new ttypes.Simple({value: 'i'})
            ]
          }
        ]
      ],
  
      struct_nested_containers_field2: {
        D: [
          {
            DA: new ttypes.Simple({value: 'j'})
          },
          {
            DB: new ttypes.Simple({value: 'k'})
          }
        ]
      }
    }
    );
  }
  
  
  function createJsObj() {
  
    return {
  
      struct_field: {value: 'a'},
  
      struct_list_field: [
        {value: 'b'},
        {value: 'c'},
      ],
  
      struct_set_field: [
        {value: 'd'},
        {value: 'e'},
      ],
  
      struct_map_field: {
        A: {value: 'f'},
        B: {value: 'g'}
      },
  
      struct_nested_containers_field: [
        [
          {
            C: [
              {value: 'h'},
              {value: 'i'}
            ]
          }
        ]
      ],
  
      struct_nested_containers_field2: {
        D: [
          {
            DA: {value: 'j'}
          },
          {
            DB: {value: 'k'}
          }
        ]
      }
    };
  }
  
  
  function assertValues(obj, assert) {
      assert.equals(obj.struct_field.value, 'a');
      assert.equals(obj.struct_list_field[0].value, 'b');
      assert.equals(obj.struct_list_field[1].value, 'c');
      assert.equals(obj.struct_set_field[0].value, 'd');
      assert.equals(obj.struct_set_field[1].value, 'e');
      assert.equals(obj.struct_map_field.A.value, 'f');
      assert.equals(obj.struct_map_field.B.value, 'g');
      assert.equals(obj.struct_nested_containers_field[0][0].C[0].value, 'h');
      assert.equals(obj.struct_nested_containers_field[0][0].C[1].value, 'i');
      assert.equals(obj.struct_nested_containers_field2.D[0].DA.value, 'j');
      assert.equals(obj.struct_nested_containers_field2.D[1].DB.value, 'k');
  }
  
  function createTestCases(serialize, deserialize) {
  
    var cases = {
  
      "Serialize/deserialize should return equal object": function(assert){
        var tObj = createThriftObj();
        var received = deserialize(serialize(tObj), ttypes.Complex);
        assert.ok(tObj !== received, 'not the same object');
        assert.deepEqual(tObj, received);
        assert.end();
      },
  
      "Nested structs and containers initialized from plain js objects should serialize same as if initialized from thrift objects": function(assert) {
        var tObj1 = createThriftObj();
        var tObj2 = new ttypes.Complex(createJsObj());
        assertValues(tObj2, assert);
        assert.ok(serialize(tObj2).equals(serialize(tObj1)));
        assert.end();
      },
  
      "Modifications to args object should not affect constructed Thrift object": function (assert) {
  
        var args = createJsObj();
        assertValues(args, assert);
  
        var tObj = new ttypes.Complex(args);
        assertValues(tObj, assert);
  
        args.struct_field.value = 'ZZZ';
        args.struct_list_field[0].value = 'ZZZ';
        args.struct_list_field[1].value = 'ZZZ';
        args.struct_set_field[0].value = 'ZZZ';
        args.struct_set_field[1].value = 'ZZZ';
        args.struct_map_field.A.value = 'ZZZ';
        args.struct_map_field.B.value = 'ZZZ';
        args.struct_nested_containers_field[0][0].C[0] = 'ZZZ';
        args.struct_nested_containers_field[0][0].C[1] = 'ZZZ';
        args.struct_nested_containers_field2.D[0].DA = 'ZZZ';
        args.struct_nested_containers_field2.D[0].DB = 'ZZZ';
  
        assertValues(tObj, assert);
        assert.end();
      },
  
      "nulls are ok": function(assert) {
        var tObj = new ttypes.Complex({
          struct_field: null,
          struct_list_field: null,
          struct_set_field: null,
          struct_map_field: null,
          struct_nested_containers_field: null,
          struct_nested_containers_field2: null
        });
        var received = deserialize(serialize(tObj), ttypes.Complex);
        assert.ok(tObj !== received);
        assert.deepEqual(tObj, received);
        assert.end();
      }
  
    };
    return cases;
  }
  
  
  function run(name, cases){
    Object.keys(cases).forEach(function(caseName) {
      test(name + ': ' + caseName, cases[caseName]);
    });
  }
  
  run('binary', createTestCases(serializeBinary, deserializeBinary));
  run('json', createTestCases(serializeJSON, deserializeJSON));
  