import { Platform } from 'react-native';
import sinon from 'sinon';

import platform from './platform';

describe('platform', function () {
  describe('isPlatform', function () {
    it('with Android platform and Android system', function () {
      Platform.OS = 'android';
      expect(platform.isPlatform('android')).toBeTruthy();
    });
    it('with Android platform and ios system', function () {
      Platform.OS = 'ios';
      expect(platform.isPlatform('android')).toBeFalsy();
    });

    it('with ios platform and Android system', function () {
      Platform.OS = 'android';
      expect(platform.isPlatform('ios')).toBeFalsy();
    });

    it('with ios platform and Android system', function () {
      Platform.OS = 'ios';
      expect(platform.isPlatform('ios')).toBeTruthy();
    });
  });

  describe('isAndroid', function () {
    it('with Android platform', function () {
      Platform.OS = 'android';
      expect(platform.isAndroid()).toBeTruthy();
    });

    it('with iOS platform', function () {
      Platform.OS = 'ios';
      expect(platform.isAndroid()).toBeFalsy();
    });
  });

  describe('isIos', function () {
    it('with Android platform', function () {
      Platform.OS = 'android';
      expect(platform.isIos()).toBeFalsy();
    });

    it('with iOS platform', function () {
      Platform.OS = 'ios';
      expect(platform.isIos()).toBeTruthy();
    });
  });

  describe('select', function () {
    it('with Android platform', function () {
      const selectStub = sinon.stub(Platform, 'select').callsFake((init) => init.android);
      expect(platform.select<string>('android-value', 'ios-value')).toBe('android-value');
      selectStub.restore();
    });

    it('with iOS platform', function () {
      const selectStub = sinon.stub(Platform, 'select').callsFake((init) => init.ios);
      expect(platform.select<string>('android-value', 'ios-value')).toBe('ios-value');
      selectStub.restore();
    });
  });

  describe('getOs', function () {
    it('with Android platform', function () {
      Platform.OS = 'android';
      expect(platform.getOs()).toBe('android');
    });

    it('with iOS platform', function () {
      Platform.OS = 'ios';
      expect(platform.getOs()).toBe('ios');
    });
  });

  describe('merge', function () {
    interface DummyStruct {
      param1: string;
      param2: string;
      param3: string;
    }
    it('with the system platform', function () {
      Platform.OS = 'android';
      expect(
        platform.merge<DummyStruct>(
          'android',
          { param1: 'test1', param2: 'test2' },
          { param3: 'test3' },
        ),
      ).toStrictEqual({
        param1: 'test1',
        param2: 'test2',
        param3: 'test3',
      });
    });

    it('with other system platform', function () {
      Platform.OS = 'ios';
      expect(
        platform.merge<DummyStruct>(
          'android',
          { param1: 'test1', param2: 'test2' },
          { param3: 'test3' },
        ),
      ).toStrictEqual({
        param1: 'test1',
        param2: 'test2',
      });
    });
  });
});
