// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'assist_processor.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ExchangeOperandsTest);
  });
}

@reflectiveTest
class ExchangeOperandsTest extends AssistProcessorTest {
  @override
  AssistKind get kind => DartAssistKind.EXCHANGE_OPERANDS;

  Future<void> test_compare() async {
    const initialOperators = ['<', '<=', '>', '>='];
    const resultOperators = ['>', '>=', '<', '<='];
    for (var i = 0; i <= 0; i++) {
      var initialOperator = initialOperators[i];
      var resultOperator = resultOperators[i];
      await resolveTestCode('''
bool f(int a, int b) {
  return a $initialOperator b;
}
''');
      await assertHasAssistAt(initialOperator, '''
bool f(int a, int b) {
  return b $resultOperator a;
}
''');
    }
  }

  Future<void> test_extended_mixOperator_1() async {
    await resolveTestCode('''
void f() {
  1 * 2 * 3 + 4;
}
''');
    await assertHasAssistAt('* 2', '''
void f() {
  2 * 3 * 1 + 4;
}
''');
  }

  Future<void> test_extended_mixOperator_2() async {
    await resolveTestCode('''
void f() {
  1 + 2 - 3 + 4;
}
''');
    await assertHasAssistAt('+ 2', '''
void f() {
  2 + 1 - 3 + 4;
}
''');
  }

  Future<void> test_extended_sameOperator_afterFirst() async {
    await resolveTestCode('''
void f() {
  1 + 2 + 3;
}
''');
    await assertHasAssistAt('+ 2', '''
void f() {
  2 + 3 + 1;
}
''');
  }

  Future<void> test_extended_sameOperator_afterSecond() async {
    await resolveTestCode('''
void f() {
  1 + 2 + 3;
}
''');
    await assertHasAssistAt('+ 3', '''
void f() {
  3 + 1 + 2;
}
''');
  }

  Future<void> test_extraLength() async {
    await resolveTestCode('''
void f() {
  111 + 222;
}
''');
    await assertNoAssistAt('+ 222', length: 3);
  }

  Future<void> test_onOperand() async {
    await resolveTestCode('''
void f() {
  111 + 222;
}
''');
    await assertNoAssistAt('11 +', length: 3);
  }

  Future<void> test_selectionWithBinary() async {
    await resolveTestCode('''
void f() {
  1 + 2 + 3;
}
''');
    await assertNoAssistAt('1 + 2 + 3', length: '1 + 2 + 3'.length);
  }

  Future<void> test_simple_afterOperator() async {
    await resolveTestCode('''
void f() {
  1 + 2;
}
''');
    await assertHasAssistAt(' 2', '''
void f() {
  2 + 1;
}
''');
  }

  Future<void> test_simple_beforeOperator() async {
    await resolveTestCode('''
void f() {
  1 + 2;
}
''');
    await assertHasAssistAt('+ 2', '''
void f() {
  2 + 1;
}
''');
  }

  Future<void> test_simple_fullSelection() async {
    await resolveTestCode('''
void f() {
  1 + 2;
}
''');
    await assertHasAssistAt(
        '1 + 2',
        '''
void f() {
  2 + 1;
}
''',
        length: '1 + 2'.length);
  }

  Future<void> test_simple_withLength() async {
    await resolveTestCode('''
void f() {
  1 + 2;
}
''');
    await assertHasAssistAt(
        '+ 2',
        '''
void f() {
  2 + 1;
}
''',
        length: 2);
  }
}
