// 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/refactoring/extract_widget.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'abstract_refactoring.dart';

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

@reflectiveTest
class ExtractWidgetTest extends RefactoringTest {
  @override
  late ExtractWidgetRefactoringImpl refactoring;

  @override
  void setUp() {
    super.setUp();
    writeTestPackageConfig(
      flutter: true,
    );
  }

  Future<void> test_checkAllConditions_selection() async {
    await indexTestUnit('''
import 'package:flutter/material.dart';
class C {}
''');
    _createRefactoringForStringOffset('class C');

    var status = await refactoring.checkAllConditions();
    assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL);
  }

  Future<void> test_checkName() async {
    await indexTestUnit('''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Text('AAA');
  }
}
''');
    _createRefactoringForStringOffset('new Text');

    // empty
    refactoring.name = '';
    assertRefactoringStatus(
        refactoring.checkName(), RefactoringProblemSeverity.FATAL,
        expectedMessage: 'Class name must not be empty.');

    // OK
    refactoring.name = 'Test';
    assertRefactoringStatusOK(refactoring.checkName());
  }

  Future<void> test_checkName_alreadyDeclared() async {
    await indexTestUnit('''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container();
  }
}

class Test {}
''');
    _createRefactoringForStringOffset('new Container');

    refactoring.name = 'Test';
    assertRefactoringStatus(
        refactoring.checkName(), RefactoringProblemSeverity.ERROR,
        expectedMessage: "Library already declares class with name 'Test'.");
  }

  Future<void> test_expression() async {
    await indexTestUnit('''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
        new Column(
          children: <Widget>[
            new Text('AAA'),
            new Text('BBB'),
          ],
        ),
        new Text('CCC'),
        new Text('DDD'),
      ],
    );
  }
}
''');
    _createRefactoringForStringOffset('new Column');

    await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
        Test(),
        new Text('CCC'),
        new Text('DDD'),
      ],
    );
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new Text('AAA'),
        new Text('BBB'),
      ],
    );
  }
}
''');
  }

  Future<void> test_expression_localFunction() async {
    await indexTestUnit('''
import 'package:flutter/material.dart';

Widget f() {
  Widget foo() {
    return new Row(
      children: <Widget>[
        new Text('AAA'),
        new Text('BBB'),
      ],
    );
  }
  return foo();
}
''');
    _createRefactoringForStringOffset('new Text');

    await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

Widget f() {
  Widget foo() {
    return new Row(
      children: <Widget>[
        Test(),
        new Text('BBB'),
      ],
    );
  }
  return foo();
}

class Test extends StatelessWidget {
  const Test({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return new Text('AAA');
  }
}
''');
  }

  Future<void> test_expression_onTypeName() async {
    await indexTestUnit('''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container();
  }
}
''');
    _createRefactoringForStringOffset('tainer(');

    await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Test();
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return new Container();
  }
}
''');
  }

  Future<void> test_expression_selection() async {
    await indexTestUnit('''
import 'package:flutter/material.dart';

Widget f() {
  return new Container();
}
''');

    Future<void> assertResult(String str) async {
      var offset = findOffset(str);
      _createRefactoring(offset, str.length);

      await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

Widget f() {
  return Test();
}

class Test extends StatelessWidget {
  const Test({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return new Container();
  }
}
''');
    }

    await assertResult('Container');
    await assertResult('new Container');
    await assertResult('new Container(');
    await assertResult('new Container()');
    await assertResult('new Container();');
    await assertResult('taine');
    await assertResult('tainer');
    await assertResult('tainer(');
    await assertResult('tainer()');
    await assertResult('turn new Container');
    await assertResult('return new Container()');
    await assertResult('return new Container();');
  }

  Future<void> test_expression_topFunction() async {
    await indexTestUnit('''
import 'package:flutter/material.dart';

Widget f() {
  return new Row(
    children: <Widget>[
      new Text('AAA'),
      new Text('BBB'),
    ],
  );
}
''');
    _createRefactoringForStringOffset('new Text');

    await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

Widget f() {
  return new Row(
    children: <Widget>[
      Test(),
      new Text('BBB'),
    ],
  );
}

class Test extends StatelessWidget {
  const Test({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return new Text('AAA');
  }
}
''');
  }

  Future<void> test_invocation_enclosingClass() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      child: new Text(''),
      onTap: () {
        foo();
      },
    );
  }

  void foo() {}
}
''');
    _createRefactoringForStringOffset('new GestureDetector');

    var status = await refactoring.checkAllConditions();
    assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR);
  }

  Future<void> test_invocation_enclosingSuperClass() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

abstract class MyInterface {
  void foo();
}

abstract class MyWidget extends StatelessWidget implements MyInterface {
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      child: new Text(''),
      onTap: () {
        foo();
      },
    );
  }
}
''');
    _createRefactoringForStringOffset('new GestureDetector');

    var status = await refactoring.checkAllConditions();
    assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR);
  }

  Future<void> test_invocation_otherClass() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class C {
  void foo() {}
}

class MyWidget extends StatelessWidget {
  C c = new C();

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      child: new Text(''),
      onTap: () {
        c.foo();
      },
    );
  }
}
''');
    _createRefactoringForStringOffset('new GestureDetector');

    await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

class C {
  void foo() {}
}

class MyWidget extends StatelessWidget {
  C c = new C();

  @override
  Widget build(BuildContext context) {
    return Test(c: c);
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
    required this.c,
  });

  final C c;

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      child: new Text(''),
      onTap: () {
        c.foo();
      },
    );
  }
}
''');
  }

  Future<void> test_method() async {
    await indexTestUnit('''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return createColumn();
  }

  Widget createColumn() {
    var a = new Text('AAA');
    var b = new Text('BBB');
    return new Column(
      children: <Widget>[a, b],
    );
  }
}
''');
    _createRefactoringForStringOffset('createColumn() {');

    await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Test();
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    var a = new Text('AAA');
    var b = new Text('BBB');
    return new Column(
      children: <Widget>[a, b],
    );
  }
}
''');
  }

  Future<void> test_method_parameters() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  String foo = '';

  @override
  Widget build(BuildContext context) {
    int bar = 1;
    return new Row(
      children: <Widget>[
        createColumn('aaa', bar),
        createColumn('bbb', 2),
      ],
    );
  }

  Widget createColumn(String p1, int p2) {
    var a = new Text('$foo $p1');
    var b = new Text('$p2');
    return new Column(
      children: <Widget>[a, b],
    );
  }
}
''');
    _createRefactoringForStringOffset('createColumn(String');

    await _assertSuccessfulRefactoring(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  String foo = '';

  @override
  Widget build(BuildContext context) {
    int bar = 1;
    return new Row(
      children: <Widget>[
        Test(foo: foo, p1: 'aaa', p2: bar),
        Test(foo: foo, p1: 'bbb', p2: 2),
      ],
    );
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
    required this.foo,
    required this.p1,
    required this.p2,
  });

  final String foo;
  final String p1;
  final int p2;

  @override
  Widget build(BuildContext context) {
    var a = new Text('$foo $p1');
    var b = new Text('$p2');
    return new Column(
      children: <Widget>[a, b],
    );
  }
}
''');
  }

  Future<void> test_method_parameters_namedRequired() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  final String foo;

  MyWidget(this.foo);

  @override
  Widget build(BuildContext context) {
    int bar = 1;
    return new Row(
      children: <Widget>[
        createColumn(p1: 'aaa', p2: bar),
        createColumn(p1: 'bbb', p2: 2),
      ],
    );
  }

  Widget createColumn({required String p1, required int p2}) {
    var a = new Text('$foo $p1');
    var b = new Text('$p2');
    return new Column(
      children: <Widget>[a, b],
    );
  }
}
''');
    _createRefactoringForStringOffset('createColumn({');

    await _assertSuccessfulRefactoring(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  final String foo;

  MyWidget(this.foo);

  @override
  Widget build(BuildContext context) {
    int bar = 1;
    return new Row(
      children: <Widget>[
        Test(foo: foo, p1: 'aaa', p2: bar),
        Test(foo: foo, p1: 'bbb', p2: 2),
      ],
    );
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
    required this.foo,
    required this.p1,
    required this.p2,
  });

  final String foo;
  final String p1;
  final int p2;

  @override
  Widget build(BuildContext context) {
    var a = new Text('$foo $p1');
    var b = new Text('$p2');
    return new Column(
      children: <Widget>[a, b],
    );
  }
}
''');
  }

  Future<void> test_parameters_field_read_enclosingClass() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  final String field;

  MyWidget(this.field);

  @override
  Widget build(BuildContext context) {
    return new Text(field);
  }
}
''');
    _createRefactoringForStringOffset('new Text');

    await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  final String field;

  MyWidget(this.field);

  @override
  Widget build(BuildContext context) {
    return Test(field: field);
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
    required this.field,
  });

  final String field;

  @override
  Widget build(BuildContext context) {
    return new Text(field);
  }
}
''');
  }

  Future<void> test_parameters_field_read_otherClass() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class C {
  String field = '';
}

class MyWidget extends StatelessWidget {
  C c = new C();

  @override
  Widget build(BuildContext context) {
    return new Text(c.field);
  }
}
''');
    _createRefactoringForStringOffset('new Text');

    await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

class C {
  String field = '';
}

class MyWidget extends StatelessWidget {
  C c = new C();

  @override
  Widget build(BuildContext context) {
    return Test(c: c);
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
    required this.c,
  });

  final C c;

  @override
  Widget build(BuildContext context) {
    return new Text(c.field);
  }
}
''');
  }

  Future<void> test_parameters_field_read_topLevelVariable() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

String field = '';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Text(field);
  }
}
''');
    _createRefactoringForStringOffset('new Text');

    await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

String field = '';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Test();
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return new Text(field);
  }
}
''');
  }

  Future<void> test_parameters_field_write_enclosingClass() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  String field;

  MyWidget(this.field);

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      child: new Text(''),
      onTap: () {
        field = '';
      },
    );
  }
}
''');
    _createRefactoringForStringOffset('new GestureDetector');

    var status = await refactoring.checkAllConditions();
    assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR);
  }

  Future<void> test_parameters_field_write_enclosingSuperClass() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

abstract class MySuperWidget extends StatelessWidget {
  String field = '';
}

class MyWidget extends MySuperWidget {
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      child: new Text(''),
      onTap: () {
        field = '';
      },
    );
  }
}
''');
    _createRefactoringForStringOffset('new GestureDetector');

    var status = await refactoring.checkAllConditions();
    assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR);
  }

  Future<void> test_parameters_field_write_otherClass() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class C {
  String field = '';
}

class MyWidget extends StatelessWidget {
  C c = new C();

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      child: new Text(''),
      onTap: () {
        c.field = '';
      },
    );
  }
}
''');
    _createRefactoringForStringOffset('new GestureDetector');

    await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

class C {
  String field = '';
}

class MyWidget extends StatelessWidget {
  C c = new C();

  @override
  Widget build(BuildContext context) {
    return Test(c: c);
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
    required this.c,
  });

  final C c;

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      child: new Text(''),
      onTap: () {
        c.field = '';
      },
    );
  }
}
''');
  }

  Future<void> test_parameters_key() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String key = '';
    return new Text('$key $key');
  }
}
''');
    _createRefactoringForStringOffset('new Text');

    var status = await refactoring.checkAllConditions();
    assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR);
  }

  Future<void> test_parameters_local_read_enclosingScope() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String local = '';
    return new Text('$local $local');
  }
}
''');
    _createRefactoringForStringOffset('new Text');

    await _assertSuccessfulRefactoring(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String local = '';
    return Test(local: local);
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
    required this.local,
  });

  final String local;

  @override
  Widget build(BuildContext context) {
    return new Text('$local $local');
  }
}
''');
  }

  Future<void> test_parameters_local_write_enclosingScope() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String local;
    return new GestureDetector(
      child: new Text(''),
      onTap: () {
        local = '';
      },
    );
  }
}
''');
    _createRefactoringForStringOffset('new GestureDetector');

    var status = await refactoring.checkAllConditions();
    assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR);
  }

  Future<void> test_parameters_private() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  final String _field;

  MyWidget(this._field);

  @override
  Widget build(BuildContext context) {
    return new Text(_field);
  }
}
''');
    _createRefactoringForStringOffset('new Text');

    await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  final String _field;

  MyWidget(this._field);

  @override
  Widget build(BuildContext context) {
    return Test(field: _field);
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
    required String field,
  }) : _field = field;

  final String _field;

  @override
  Widget build(BuildContext context) {
    return new Text(_field);
  }
}
''');
  }

  Future<void> test_parameters_private_conflictWithPublic() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  final int field;
  final String _field;

  MyWidget(this.field, this._field);

  @override
  Widget build(BuildContext context) {
    return new Text('$field $_field');
  }
}
''');
    _createRefactoringForStringOffset('new Text');

    await _assertSuccessfulRefactoring(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  final int field;
  final String _field;

  MyWidget(this.field, this._field);

  @override
  Widget build(BuildContext context) {
    return Test(field: field, field2: _field);
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
    required this.field,
    required String field2,
  }) : _field = field2;

  final int field;
  final String _field;

  @override
  Widget build(BuildContext context) {
    return new Text('$field $_field');
  }
}
''');
  }

  Future<void> test_parameters_readField_readLocal() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  final String field;

  MyWidget(this.field);

  @override
  Widget build(BuildContext context) {
    String local = '';
    return new Column(
      children: <Widget>[
        new Text(field),
        new Text(local),
      ],
    );
  }
}
''');
    _createRefactoringForStringOffset('new Column');

    await _assertSuccessfulRefactoring('''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  final String field;

  MyWidget(this.field);

  @override
  Widget build(BuildContext context) {
    String local = '';
    return Test(field: field, local: local);
  }
}

class Test extends StatelessWidget {
  const Test({
    super.key,
    required this.field,
    required this.local,
  });

  final String field;
  final String local;

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new Text(field),
        new Text(local),
      ],
    );
  }
}
''');
  }

  Future<void> test_refactoringName() async {
    await indexTestUnit('''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Text('AAA');
  }
}
''');
    _createRefactoringForStringOffset('new Text');
    expect(refactoring.refactoringName, 'Extract Widget');
  }

  Future<void> test_statements() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

Widget f() {
  var index = 0;
  var a = 'a $index';
// start
  var b = 'b $index';
  return new Row(
    children: <Widget>[
      new Text(a),
      new Text(b),
    ],
  );
// end
}
''');
    _createRefactoringForStartEnd();

    await _assertSuccessfulRefactoring(r'''
import 'package:flutter/material.dart';

Widget f() {
  var index = 0;
  var a = 'a $index';
// start
  return Test(index: index, a: a);
// end
}

class Test extends StatelessWidget {
  const Test({
    super.key,
    required this.index,
    required this.a,
  });

  final int index;
  final String a;

  @override
  Widget build(BuildContext context) {
    var b = 'b $index';
    return new Row(
      children: <Widget>[
        new Text(a),
        new Text(b),
      ],
    );
  }
}
''');
  }

  Future<void> test_statements_BAD_emptySelection() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

void f() {
// start
// end
}
''');
    _createRefactoringForStartEnd();

    assertRefactoringStatus(await refactoring.checkInitialConditions(),
        RefactoringProblemSeverity.FATAL);
  }

  Future<void> test_statements_BAD_notReturnStatement() async {
    await indexTestUnit(r'''
import 'package:flutter/material.dart';

void f() {
// start
  new Text('text');
// end
}
''');
    _createRefactoringForStartEnd();

    assertRefactoringStatus(await refactoring.checkInitialConditions(),
        RefactoringProblemSeverity.FATAL);
  }

  Future<void> test_useSuperParameters_disabled() async {
    await indexTestUnit('''
// No super params.    
// @dart = 2.15
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
        new Column(
          children: <Widget>[
            new Text('AAA'),
            new Text('BBB'),
          ],
        ),
        new Text('CCC'),
        new Text('DDD'),
      ],
    );
  }
}
''');
    _createRefactoringForStringOffset('new Column');

    await _assertSuccessfulRefactoring('''
// No super params.    
// @dart = 2.15
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
        Test(),
        new Text('CCC'),
        new Text('DDD'),
      ],
    );
  }
}

class Test extends StatelessWidget {
  const Test({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new Text('AAA'),
        new Text('BBB'),
      ],
    );
  }
}
''');
  }

  Future<void> _assertRefactoringChange(String expectedCode) async {
    var refactoringChange = await refactoring.createChange();
    this.refactoringChange = refactoringChange;
    assertTestChangeResult(expectedCode);
  }

  /// Checks that all conditions are OK and the result of applying the change
  /// to [testUnit] is [expectedCode].
  Future<void> _assertSuccessfulRefactoring(String expectedCode) async {
    await assertRefactoringConditionsOK();
    await _assertRefactoringChange(expectedCode);
  }

  void _createRefactoring(int offset, int length) {
    refactoring = ExtractWidgetRefactoringImpl(
        searchEngine, testAnalysisResult, offset, length);
    refactoring.name = 'Test';
  }

  void _createRefactoringForStartEnd() {
    var offset = findOffset('// start\n') + '// start\n'.length;
    var length = findOffset('// end') - offset;
    _createRefactoring(offset, length);
  }

  /// Creates a new refactoring in [refactoring] at the offset of the given
  /// [search] pattern.
  void _createRefactoringForStringOffset(String search) {
    var offset = findOffset(search);
    _createRefactoring(offset, 0);
  }
}
