test: fix tests steps implement
This commit is contained in:
parent
ad37861303
commit
eb19022572
|
@ -1,4 +1,5 @@
|
||||||
# Non-Functional Requirements
|
# Non-Functional Requirements
|
||||||
|
|
||||||
* Package structure
|
* support multiple platforms (windows, linux, android, web)
|
||||||
* plz follow official [Package structure](https://docs.flutter.dev/app-architecture/case-study#package-structure) with a slight modification, put each `<FEATURE NAME>/`s in `features/` sub-directory under `ui/`.
|
* only FOSS libs can use
|
||||||
|
* recommend no more than 300 lines of code per file
|
||||||
|
|
|
@ -2,3 +2,10 @@
|
||||||
|
|
||||||
* [MVVM](https://docs.flutter.dev/app-architecture/guide)
|
* [MVVM](https://docs.flutter.dev/app-architecture/guide)
|
||||||
|
|
||||||
|
## Package structure
|
||||||
|
|
||||||
|
The repo structure follows official [Package structure](https://docs.flutter.dev/app-architecture/case-study#package-structure) with slight modifications.
|
||||||
|
|
||||||
|
* put each `<FEATURE NAME>/`s in `features/` sub-directory under `ui/`.
|
||||||
|
* `test/features/` contains BDD unit tests for each feature. It focuses on pure logic, therefore will not access `View` but `ViewModel` and `Model`.
|
||||||
|
* `test/widget/` contains UI widget(component) tests which focus on `View` of MVVM only.
|
||||||
|
|
|
@ -4,7 +4,7 @@ Feature: App preferences
|
||||||
Given the settings screen is open
|
Given the settings screen is open
|
||||||
When the user selects the "<theme>" theme
|
When the user selects the "<theme>" theme
|
||||||
Then the app UI updates to use the "<theme>" theme
|
Then the app UI updates to use the "<theme>" theme
|
||||||
And the preference {theme} is saved as {"<theme>"}
|
And the preference {'theme'} is saved as <theme>
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
| theme |
|
| theme |
|
||||||
|
@ -16,7 +16,7 @@ Feature: App preferences
|
||||||
Given the settings screen is open
|
Given the settings screen is open
|
||||||
When the user selects a supported language "<language>"
|
When the user selects a supported language "<language>"
|
||||||
Then all visible texts are displayed in "<language>"
|
Then all visible texts are displayed in "<language>"
|
||||||
And the preference {language} is saved as {"<language>"}
|
And the preference {'language'} is saved as <language>
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
| language |
|
| language |
|
||||||
|
|
|
@ -10,4 +10,7 @@ Feature: internationalizing
|
||||||
Then the language falls back to the device locale
|
Then the language falls back to the device locale
|
||||||
|
|
||||||
Scenario: Supported languages are available
|
Scenario: Supported languages are available
|
||||||
Then the app supports languages {en, zh-TW, es}
|
Then the app supports languages
|
||||||
|
| 'en' |
|
||||||
|
| 'zh-TW' |
|
||||||
|
| 'es' |
|
||||||
|
|
|
@ -17,4 +17,11 @@ Future<void> aSignatureImageIsSelected(WidgetTester tester) async {
|
||||||
.setImageBytes(Uint8List.fromList([1, 2, 3]));
|
.setImageBytes(Uint8List.fromList([1, 2, 3]));
|
||||||
// Allow provider scheduler to process queued updates fully
|
// Allow provider scheduler to process queued updates fully
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
// Extra pump with a non-zero duration to flush zero-delay timers
|
||||||
|
await tester.pump(const Duration(milliseconds: 1));
|
||||||
|
// Teardown to avoid pending timers from Riverpod's scheduler
|
||||||
|
addTearDown(() {
|
||||||
|
TestWorld.container?.dispose();
|
||||||
|
TestWorld.container = null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,33 @@
|
||||||
|
import 'package:bdd_widget_test/data_table.dart' as bdd;
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
/// Usage: the app supports languages {en, zh-TW, es}
|
/// Usage: the app supports languages
|
||||||
|
/// | 'en' |
|
||||||
|
/// | 'zh-TW' |
|
||||||
|
/// | 'es' |
|
||||||
Future<void> theAppSupportsLanguages(
|
Future<void> theAppSupportsLanguages(
|
||||||
WidgetTester tester,
|
WidgetTester tester,
|
||||||
String languages,
|
dynamic languages,
|
||||||
) async {
|
) async {
|
||||||
// Normalize the example token string "{en, zh-TW, es}" into a set
|
// Accept either a DataTable from bdd_widget_test or a string like "{en, zh-TW, es}"
|
||||||
final raw = languages.trim();
|
final Set<String> expected;
|
||||||
final inner =
|
if (languages is bdd.DataTable) {
|
||||||
raw.startsWith('{') && raw.endsWith('}')
|
final lists = languages.asLists();
|
||||||
? raw.substring(1, raw.length - 1)
|
// Flatten ignoring header rows if any
|
||||||
: raw;
|
final items = lists
|
||||||
final expected = inner.split(',').map((s) => s.trim()).toSet();
|
.skipWhile((row) => row.any((e) => e.toString().contains('artist') || e.toString().contains('name')))
|
||||||
|
.expand((row) => row)
|
||||||
|
.map((e) => e.toString().replaceAll("'", '').trim())
|
||||||
|
.where((e) => e.isNotEmpty)
|
||||||
|
.toSet();
|
||||||
|
expected = items;
|
||||||
|
} else {
|
||||||
|
final raw = languages.toString().trim();
|
||||||
|
final inner = raw.startsWith('{') && raw.endsWith('}')
|
||||||
|
? raw.substring(1, raw.length - 1)
|
||||||
|
: raw;
|
||||||
|
expected = inner.split(',').map((s) => s.trim().replaceAll("'", '')).toSet();
|
||||||
|
}
|
||||||
|
|
||||||
// Keep this in sync with the app's supported locales
|
// Keep this in sync with the app's supported locales
|
||||||
const actual = {'en', 'zh-TW', 'es'};
|
const actual = {'en', 'zh-TW', 'es'};
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import '_world.dart';
|
import '_world.dart';
|
||||||
|
// Re-export tokens so tests that import this step have access to token symbols
|
||||||
|
export '_tokens.dart';
|
||||||
|
|
||||||
/// Usage: the preference {language} is saved as {"<language>"}
|
/// Usage: the preference {language} is saved as {"<language>"}
|
||||||
Future<void> thePreferenceIsSavedAs(
|
Future<void> thePreferenceIsSavedAs(
|
||||||
|
|
Loading…
Reference in New Issue