Skip to content

Commit

Permalink
test workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexHCJP committed Oct 22, 2024
1 parent dfee768 commit e7c478f
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 35 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/checkout.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ jobs:

# Consider passing '--fatal-infos' for slightly stricter analysis.
- name: Analyze project source
run: dart analyze
run: flutter test

- name: Analyze project source
run: flutter analyze

# Your project will need to have tests in test/ and a dependency on
# package:test for this step to succeed. Note that Flutter projects will
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 5.0.1

* Format files

## 5.0.0

* Big version
Expand Down
1 change: 0 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import 'package:example/src/screens/create_quest_screen.dart';
import 'package:example/src/screens/exception_multi_screen.dart';
import 'package:example/src/screens/login_screen.dart';
Expand Down
1 change: 0 additions & 1 deletion example/lib/src/forms/create_quest_form.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import 'package:fform/fform.dart';

import '../fields/fields.dart';
Expand Down
1 change: 0 additions & 1 deletion example/lib/src/screens/login_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ class _LoginScreenState extends State<LoginScreen> {
}
}


@override
void initState() {
_emailController = TextEditingController();
Expand Down
24 changes: 16 additions & 8 deletions lib/src/fform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,15 @@ abstract class FForm extends ChangeNotifier {

/// Get the first field of a specific type.
@nonVirtual
T get<T extends FFormField<_NullObject, _NullObject>>() => fields.whereType<T>().cast<T>().first;
T get<T extends FFormField<_NullObject, _NullObject>>() =>
fields.whereType<T>().cast<T>().first;

/// List of all fields of the form.
List<FFormField<_NullObject, _NullObject>> get _allFields => [...fields, ..._subFormFields];
List<FFormField<_NullObject, _NullObject>> get _allFields =>
[...fields, ..._subFormFields];

List<FFormField<_NullObject, _NullObject>> get _subFormFields => [for (final subForm in subForms) ...subForm.fields];
List<FFormField<_NullObject, _NullObject>> get _subFormFields =>
[for (final subForm in subForms) ...subForm.fields];

/// List of answers of the fields.
@nonVirtual
Expand All @@ -130,19 +133,23 @@ abstract class FForm extends ChangeNotifier {

/// List of exceptions of the fields.
@nonVirtual
List<_NullObject> get exceptionFields => answerFields.where((element) => element != null).toList();
List<_NullObject> get exceptionFields =>
answerFields.where((element) => element != null).toList();

/// List of exceptions of the sub forms.
@nonVirtual
List<_NullObject> get exceptionSubForms => answersSubForms.where((element) => element != null).toList();
List<_NullObject> get exceptionSubForms =>
answersSubForms.where((element) => element != null).toList();

/// List of all exceptions of the fields and sub forms.
@nonVirtual
List<_NullObject> get exceptions => answers.where((element) => element != null).toList();
List<_NullObject> get exceptions =>
answers.where((element) => element != null).toList();

/// Check if the form is valid.
@nonVirtual
bool get isValid => _allFields.fold(true, (previousValue, field) => previousValue && field.isValid);
bool get isValid => _allFields.fold(
true, (previousValue, field) => previousValue && field.isValid);

/// Check if the form is invalid.
@nonVirtual
Expand All @@ -155,5 +162,6 @@ abstract class FForm extends ChangeNotifier {

///Get the last field with an exception.
@nonVirtual
FFormField<_NullObject, _NullObject>? get lastInvalidField => _allFields.lastWhereOrNull((field) => field.isInvalid);
FFormField<_NullObject, _NullObject>? get lastInvalidField =>
_allFields.lastWhereOrNull((field) => field.isInvalid);
}
17 changes: 11 additions & 6 deletions lib/src/widgets/fform_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,22 @@ class FFormProvider<T extends FForm> extends InheritedNotifier<T> {
}) : super(notifier: form);

/// Retrieves the form from the context.
static T? maybeOf<T extends FForm>(BuildContext context, {bool listen = false}) => listen
? context.dependOnInheritedWidgetOfExactType<FFormProvider<T>>()?.notifier
: context.getInheritedWidgetOfExactType<FFormProvider<T>>()?.notifier;
static T? maybeOf<T extends FForm>(BuildContext context,
{bool listen = false}) =>
listen
? context
.dependOnInheritedWidgetOfExactType<FFormProvider<T>>()
?.notifier
: context.getInheritedWidgetOfExactType<FFormProvider<T>>()?.notifier;

static Never _notFound() =>
throw ArgumentError('FFormProvider.of() called with a context that does not contain a FFormProvider.');
static Never _notFound() => throw ArgumentError(
'FFormProvider.of() called with a context that does not contain a FFormProvider.');

/// Retrieves the form from the context.
static T of<T extends FForm>(BuildContext context, {bool listen = true}) =>
maybeOf<T>(context, listen: listen) ?? _notFound();

@override
bool updateShouldNotify(covariant InheritedNotifier<T> oldWidget) => notifier != oldWidget.notifier;
bool updateShouldNotify(covariant InheritedNotifier<T> oldWidget) =>
notifier != oldWidget.notifier;
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: fform
description: FForm is a dart package to build forms with a lot of fields and validations.
version: 5.0.0
version: 5.0.1

homepage: https://github.com/AlexHCJP/fform

Expand Down
9 changes: 6 additions & 3 deletions test/builder_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ class MockForm extends FForm {}

void main() {
group('FFormBuilder Tests', () {
testWidgets('FFormBuilder builds form and provides it to builder', (tester) async {
testWidgets('FFormBuilder builds form and provides it to builder',
(tester) async {
final form = MockForm();

await tester.pumpWidget(
Expand Down Expand Up @@ -50,7 +51,8 @@ void main() {
expect(didRebuild, true);
});

testWidgets('FFormBuilder provides form through FFormProvider', (tester) async {
testWidgets('FFormBuilder provides form through FFormProvider',
(tester) async {
final form = MockForm();

await tester.pumpWidget(
Expand Down Expand Up @@ -93,7 +95,8 @@ void main() {
expect(rebuildCount, 2);
});

testWidgets('FFormBuilder does not rebuild if form does not update', (tester) async {
testWidgets('FFormBuilder does not rebuild if form does not update',
(tester) async {
final form = MockForm();
var rebuildCount = 0;

Expand Down
3 changes: 2 additions & 1 deletion test/field_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ void main() {
});

test('Setting exception manually should update field state', () {
final field = TestFFormField(10)..exception = MockException(isValid: false);
final field = TestFFormField(10)
..exception = MockException(isValid: false);

expect(field.isValid, false);
expect(field.exception!.isValid, false);
Expand Down
22 changes: 15 additions & 7 deletions test/form_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ void main() {
expect(form.isValid, true);
});

test('Async validation works and form becomes valid after corrections', () async {
test('Async validation works and form becomes valid after corrections',
() async {
final form = MockForm();
final invalidField = MockFFormField('');

Expand All @@ -58,10 +59,13 @@ void main() {
expect(await form.checkAsync(), false); // Initial validation fails

invalidField.value = 'Corrected value';
expect(await form.checkAsync(), true); // After correction, validation passes
expect(
await form.checkAsync(), true); // After correction, validation passes
});

test('Form correctly tracks multiple fields with different validation states', () {
test(
'Form correctly tracks multiple fields with different validation states',
() {
final form = MockForm();
final validField = MockFFormField('Valid value');
final invalidField = MockFFormField('');
Expand All @@ -78,18 +82,21 @@ void main() {
expect(form.isValid, true);
});

test('Subforms are correctly integrated into the validation flow', () async {
test('Subforms are correctly integrated into the validation flow',
() async {
final subForm = MockForm();
final form = MockForm()..addSubForm(subForm);
final fieldInSubForm = MockFFormField(null); // Invalid field

subForm.addField(fieldInSubForm);

expect(form.isValid, false);
expect(await form.checkAsync(), false); // Entire form is invalid due to subform
expect(await form.checkAsync(),
false); // Entire form is invalid due to subform

fieldInSubForm.value = 'Valid input';
expect(await form.checkAsync(), true); // Now both form and subform are valid
expect(
await form.checkAsync(), true); // Now both form and subform are valid
});

test('Adding and removing fields dynamically works correctly', () {
Expand Down Expand Up @@ -172,7 +179,8 @@ void main() {
expect(await form.checkAsync(), false); // SubForm 2 is invalid

fieldInSubForm2.value = 'Valid';
expect(await form.checkAsync(), true); // Now all subforms and fields are valid
expect(await form.checkAsync(),
true); // Now all subforms and fields are valid
});
});
}
19 changes: 14 additions & 5 deletions test/provider_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ void main() {
);
});

testWidgets('maybeOf returns null when no form is provided', (tester) async {
testWidgets('maybeOf returns null when no form is provided',
(tester) async {
await tester.pumpWidget(
Builder(
builder: (context) {
Expand Down Expand Up @@ -57,7 +58,8 @@ void main() {
);
});

testWidgets('updateShouldNotify returns true when form changes', (tester) async {
testWidgets('updateShouldNotify returns true when form changes',
(tester) async {
final form1 = MockForm();
final form2 = MockForm();

Expand All @@ -66,18 +68,25 @@ void main() {
child: const SizedBox(),
);

expect(provider.updateShouldNotify(FFormProvider(form: form2, child: const SizedBox())), true);
expect(
provider.updateShouldNotify(
FFormProvider(form: form2, child: const SizedBox())),
true);
});

testWidgets('updateShouldNotify returns false when form does not change', (tester) async {
testWidgets('updateShouldNotify returns false when form does not change',
(tester) async {
final form = MockForm();

final provider = FFormProvider<MockForm>(
form: form,
child: const SizedBox(),
);

expect(provider.updateShouldNotify(FFormProvider(form: form, child: const SizedBox())), false);
expect(
provider.updateShouldNotify(
FFormProvider(form: form, child: const SizedBox())),
false);
});
});
}

0 comments on commit e7c478f

Please sign in to comment.