// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

import 'package:flutter_test/flutter_test.dart';
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';

void main() {
  final WyattForm formA = WyattFormImpl(
    [
      FormInput(
        'email',
        const Email.dirty('test@test.fr'),
      ),
      FormInput(
        'password',
        const Password.pure(),
      ),
    ],
    name: 'A',
  );

  final WyattForm formB = WyattFormImpl(
    [
      FormInput(
        'email',
        const Email.dirty('test2@test.fr'),
      ),
      FormInput(
        'password',
        const Password.dirty('password1234'),
      ),
      FormInput(
        'bool',
        const Boolean.pure(),
      ),
      FormInput(
        'phone',
        const Phone.dirty('0000000000'),
      ),
    ],
    name: 'B',
  );

  group('FormReplace', () {
    test('returns B when called on (A,B)', () {
      final result = const FormReplace().call(formA, formB);
      expect(result, formB);
    });

    test('returns A when called on (A,A)', () {
      final result = const FormReplace().call(formA, formA);
      expect(result, formA);
    });
  });

  group('FormUnion', () {
    final WyattForm union = WyattFormImpl(
      [
        FormInput(
          'email',
          const Email.dirty('test@test.fr'),
        ),
        FormInput(
          'password',
          const Password.dirty('password1234'),
        ),
        FormInput(
          'bool',
          const Boolean.pure(),
        ),
        FormInput(
          'phone',
          const Phone.dirty('0000000000'),
        ),
      ],
      name: 'A',
    );

    test('returns A union B when called on (A,B), with A name', () {
      final result = const FormUnion().call(formA, formB);
      expect(result, union);
    });
  });

  group('FormIntersection', () {
    final WyattForm intersection = WyattFormImpl(
      [
        FormInput(
          'email',
          const Email.dirty('test@test.fr'),
        ),
        FormInput(
          'password',
          const Password.dirty('password1234'),
        ),
      ],
      name: 'A',
    );

    test('returns A intersection B when called on (A,B), with A name', () {
      final result = const FormIntersection().call(formA, formB);
      expect(result, intersection);
    });
  });

  group('FormDifference', () {
    test('returns A - B when called on (A,B), with A name', () {
      final result = const FormDifference().call(formA, formB);
      expect(
        result,
        WyattFormImpl(
          const [],
          name: 'A',
        ),
      );
    });
    final WyattForm difference = WyattFormImpl(
      [
        FormInput(
          'bool',
          const Boolean.pure(),
        ),
        FormInput(
          'phone',
          const Phone.dirty('0000000000'),
        ),
      ],
      name: 'B',
    );

    test('returns B - A when called on (B,A), with B name', () {
      final result = const FormDifference().call(formB, formA);
      expect(result, difference);
    });
  });
}
