addAppTests function

List<String> addAppTests(
  1. List<MatrixAppTest> tests, {
  2. required String directory,
  3. required String packageName,
  4. MatrixApp? app,
  5. FileSystem fileSystem = const LocalFileSystem(),
})

Copies the files of tests into the app of the matrix app, generated in directory with the package packageName, with the placeholders of the files filled, writes the files that the tests generate for the app next to them, and returns the paths of the files in the app; see MatrixAppTest.directory and MatrixAppTest.generatedFiles.

Without app, for an app that smf create generated outside the matrix, only {{app_name}} is filled: the MatrixAppTest.values come from an app of the matrix, and so do the files that the tests generate.

If some of the tests declare MatrixAppTest.mocks, it also writes the configuration of the tests of the app, test/flutter_test_config.dart, with which flutter test runs each test file in test/: in a setUpAll that runs before those of the file, it initializes the binding of the tests and calls the function of the mocks of each of those tests, in the order of the tests. So the mocks of every module of an app are set up for the tests of each module, which the tests of the matrix and the tests added to an app outside it get alike.

If some of the tests run the probes of the tests of the app (MatrixAppTest.readsStartProbes), such as the start check, it also writes the list of the probes of the tests, startProbesFile, in the order of the tests, each named after the directory of its tests. So the start check that the matrix analyzes in its apps and the one that CI starts on a device run the probes of the tests that go into the app.

Throws a MatrixAppTestException, before it copies anything, if a test generates files without app, if a file keeps a placeholder that no value fills, if two of the tests have a file at the same path, the files they generate included, if a test generates a file at a path that is no relative path in the app, if the mocks of a test are in no file of it in test/, if its probe is in no file of it in integration_test/, or if a test has a file at the path of the configuration of the mocks or of the list of the probes, which the matrix writes.

Implementation

List<String> addAppTests(
  List<MatrixAppTest> tests, {
  required String directory,
  required String packageName,
  MatrixApp? app,
  FileSystem fileSystem = const LocalFileSystem(),
}) {
  final context = fileSystem.path;
  final (:texts, :owners) = _filesOfTests(
    tests,
    packageName: packageName,
    app: app,
    fileSystem: fileSystem,
  );
  final mocks = _mocksOf(tests, owners, fileSystem);
  if (mocks.isNotEmpty) {
    final config = context.joinAll(_testConfig.split('/'));
    if (owners[config] case final other?) {
      throw MatrixAppTestException(
        'The tests of $other have $_testConfig, which the matrix writes for '
        'the mocks of the tests.',
      );
    }
    texts[config] = _testConfigOf(mocks);
  }
  final probes = _probesOf(tests, owners, fileSystem);
  if (tests.any((test) => test.readsStartProbes)) {
    final list = context.joinAll(startProbesFile.split('/'));
    if (owners[list] case final other?) {
      throw MatrixAppTestException(
        'The tests of $other have $startProbesFile, which the matrix writes '
        'for the probes of the tests.',
      );
    }
    texts[list] = _startProbesOf(probes);
  }
  for (final MapEntry(key: path, value: text) in texts.entries) {
    fileSystem.file(context.join(directory, path))
      ..createSync(recursive: true)
      ..writeAsStringSync(text);
  }
  return [...texts.keys];
}