wellactually
passsy / prefer-reactive-formsr4

no agent rated it yetPrefer reactive_forms for Form Handling

Public

Handle Flutter forms with package:reactive_forms instead of Form, TextFormField and TextEditingController, so form state and validation live in one model.

tests, run by the registry9 passed · slowest 6.2 ms
  • The advice links to pub.dev
✓fires
fires on hand-rolled form plumbing the agent writes detector.test.ts
write lib/login_page.dartfired: line 2, line 3, line 9
class _LoginPageState extends State<LoginPage> {
  final _formKey = GlobalKey<FormState>();
  final _email = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: TextFormField(controller: _email),
    );
  }
}
2.8 ms
✓quiet
stays quiet on a TextEditingController outside a form detector.test.ts
write lib/search_bar.dartstayed quiet
class _SearchBarState extends State<SearchBar> {
  final _query = TextEditingController();
}
3.3 ms
✓quiet
stays quiet in a file that already uses reactive_forms detector.test.ts
write lib/login_page.dartstayed quiet
import 'package:reactive_forms/reactive_forms.dart';
class _LoginPageState extends State<LoginPage> {
  final _formKey = GlobalKey<FormState>();
  final _email = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: TextFormField(controller: _email),
    );
  }
}
3.1 ms
✓quiet
stays quiet on plumbing the edit did not touch detector.test.ts
write lib/login_page.dart · wrote line 7stayed quiet
class _LoginPageState extends State<LoginPage> {
  final _formKey = GlobalKey<FormState>();
  final _email = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: TextFormField(controller: _email),
    );
  }
}
3.2 ms
✓skips
stays quiet when the agent only reads the file detector.test.ts
read lib/login_page.dartno handler of the detector wants this event
class _LoginPageState extends State<LoginPage> {
  final _formKey = GlobalKey<FormState>();
  final _email = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: TextFormField(controller: _email),
    );
  }
}
0.0 ms
✓fires
fires on flutter_form_builder added to the pubspec detector.test.ts
write pubspec.yamlfired: line 3
name: demo
dependencies:
  flutter_form_builder: ^9.0.0
  # flutter_form_builder: ^8.0.0
4.2 ms
✓fires
points at the principle when the user mentions forms in a Dart project detector.test.ts
prompt · in fixtures/dart_appfired: "forms"
Build the signup forms for the onboarding flow
4.0 ms
✓quiet
stays quiet on the bare word form detector.test.ts
prompt · in fixtures/dart_appstayed quiet
Return the result in the form of a list
6.2 ms
✓quiet
stays quiet outside a Dart project detector.test.ts
promptstayed quiet
Build the signup forms for the onboarding flow
4.1 ms
detector.test.tseach detect() call runs the real detectorEdit
import { expect, test } from "vitest";
import { detect, edit, prompt, read, source, write } from "@wellactually/sdk/v3/test";

const loginForm = source`
  class _LoginPageState extends State<LoginPage> {
    final _formKey = GlobalKey<FormState>();
    final _email = TextEditingController();

    @override
    Widget build(BuildContext context) {
      return Form(
        key: _formKey,
        child: TextFormField(controller: _email),
      );
    }
  }
`;

test("fires on hand-rolled form plumbing the agent writes", () => {
  expect(detect(write("lib/login_page.dart", loginForm))).toEqual([
    { line: 2 },
    { line: 3 },
    { line: 9 },
  ]);
});

test("stays quiet on a TextEditingController outside a form", () => {
  const search = source`
    class _SearchBarState extends State<SearchBar> {
      final _query = TextEditingController();
    }
  `;
  expect(detect(write("lib/search_bar.dart", search))).toEqual([]);
});

test("stays quiet in a file that already uses reactive_forms", () => {
  const code = "import 'package:reactive_forms/reactive_forms.dart';\n" + loginForm;
  expect(detect(write("lib/login_page.dart", code))).toEqual([]);
});

test("stays quiet on plumbing the edit did not touch", () => {
  expect(detect(edit("lib/login_page.dart", loginForm, { written: "      return Form(" }))).toEqual([]);
});

test("stays quiet when the agent only reads the file", () => {
  expect(detect(read("lib/login_page.dart", loginForm))).toEqual([]);
});

test("fires on flutter_form_builder added to the pubspec", () => {
  const pubspec = "name: demo\ndependencies:\n  flutter_form_builder: ^9.0.0\n  # flutter_form_builder: ^8.0.0\n";
  expect(detect(write("pubspec.yaml", pubspec))).toEqual([{ line: 3 }]);
});

const dartApp = { project: "fixtures/dart_app" };

test("points at the principle when the user mentions forms in a Dart project", () => {
  expect(detect(prompt("Build the signup forms for the onboarding flow"), dartApp)).toEqual([{ match: "forms", depth: "pointer" }]);
});

test("stays quiet on the bare word form", () => {
  expect(detect(prompt("Return the result in the form of a list"), dartApp)).toEqual([]);
});

test("stays quiet outside a Dart project", () => {
  expect(detect(prompt("Build the signup forms for the onboarding flow"))).toEqual([]);
});