"use strict";

require("../../injector");

var _ = require(".");

// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
describe('createType', () => {
  it('allows creation of a Struct', () => {
    expect((0, _.createTypeUnsafe)('{"balance":"Balance","index":"u32"}', [{
      balance: 1234,
      index: '0x10'
    }]).toJSON()).toEqual({
      balance: 1234,
      index: 16
    });
  });
  it('allows creation of a BTreeMap', () => {
    expect((0, _.createTypeUnsafe)('BTreeMap<Text,u32>', ['0x041c62617a7a696e6745000000']).toString()).toEqual('{"bazzing":69}');
  });
  it('allows creation of a Result', () => {
    expect((0, _.createTypeUnsafe)('Result<u32,Text>', ['0x011064656667']).toJSON()).toEqual({
      Error: 'defg'
    });
  });
  it('allows creation of a Tuple', () => {
    expect((0, _.createTypeUnsafe)('(Balance,u32)', [[1234, 5678]]).toJSON()).toEqual([1234, 5678]);
  });
  it('allows creation of a Enum (simple)', () => {
    expect((0, _.createTypeUnsafe)('{"_enum": ["A", "B", "C"]}', [1]).toJSON()).toEqual(1);
  });
  it('allows creation of a Enum (parametrised)', () => {
    expect((0, _.createTypeUnsafe)('{"_enum": {"A": null, "B": "u32", "C": null} }', [1]).toJSON()).toEqual({
      B: 0
    });
  });
  it('allows creation of a Set', () => {
    expect((0, _.createTypeUnsafe)('{"_set": { "A": 1, "B": 2, "C": 4, "D": 8, "E": 16, "G": 32, "H": 64, "I": 128 } }', [1 + 4 + 16 + 64]).strings).toEqual(['A', 'C', 'E', 'H']);
  });
  it('allows creation of a [u8; 8]', () => {
    expect((0, _.createTypeUnsafe)('[u8; 8]', [[0x12, 0x00, 0x23, 0x00, 0x45, 0x00, 0x67, 0x00]]).toHex()).toEqual('0x1200230045006700');
  });
  it('allows creation of a [u16; 4]', () => {
    expect((0, _.createTypeUnsafe)('[u16; 4]', [[0x1200, 0x2300, 0x4500, 0x6700]]).toU8a()).toEqual(new Uint8Array([0x00, 0x12, 0x00, 0x23, 0x00, 0x45, 0x00, 0x67]));
  });
  describe('instanceof', () => {
    it('instanceof should work (primitive type)', () => {
      const value = (0, _.createType)('Balance', 1234);
      expect(value instanceof (0, _.ClassOf)('Balance')).toBe(true);
    });
    it('instanceof should work (srml type)', () => {
      const value = (0, _.createType)('Gas', 1234);
      const Gas = (0, _.ClassOf)('Gas');
      expect(value instanceof Gas).toBe(true);
    });
    it('instanceof should work (complex type)', () => {
      (0, _.getTypeRegistry)().register({
        TestComplex: {
          balance: 'Balance',
          accountId: 'AccountId',
          log: '(u64, u32)',
          fromSrml: 'Gas'
        }
      });
      const value = (0, _.createTypeUnsafe)('TestComplex', [{
        balance: 123,
        accountId: '0x1234567812345678123456781234567812345678123456781234567812345678',
        log: [456, 789],
        fromSrml: 0
      }]);
      expect(value instanceof (0, _.createClass)('TestComplex')).toBe(true);
    });
    it('allows for re-registration of a type', () => {
      const balDef = (0, _.createType)('Balance');
      expect(balDef instanceof (0, _.ClassOf)('Balance'));
      expect(balDef.bitLength()).toEqual(128);
      (0, _.getTypeRegistry)().register({
        Balance: 'u32'
      });
      const balu32 = (0, _.createType)('Balance');
      expect(balu32 instanceof (0, _.ClassOf)('Balance'));
      expect(balu32.bitLength()).toEqual(32);
    });
    it('allows for re-registration of a type (affecting derives)', () => {
      (0, _.getTypeRegistry)().register({
        Balance: 'u128',
        TestComplex: {
          balance: 'Balance',
          accountId: 'AccountId',
          log: '(u64, u32)',
          fromSrml: 'Gas'
        }
      });
      const cmpDef = (0, _.createTypeUnsafe)('TestComplex');
      expect(cmpDef.balance.bitLength()).toEqual(128);
      (0, _.getTypeRegistry)().register({
        Balance: 'u32'
      });
      const cmpu32 = (0, _.createTypeUnsafe)('TestComplex');
      expect(cmpu32.balance.bitLength()).toEqual(32);
    });
  });
});