FirebaseFirestoreFake.stateful constructor
FirebaseFirestoreFake.stateful({
- Map<
String, CollectionReferenceFake> ? collections, - void onCollectionChanged(
- String path,
- Map<
String, DocumentReferenceFake> collectionDocuments, - List<
QueryFakeAndStreamController> queries
Creates a stateful FirebaseFirestore fake that maintains its own state and aims to mimic firebase as closely as possible
Implementation
factory FirebaseFirestoreFake.stateful({
Map<String, CollectionReferenceFake>? collections,
void Function(
String path,
Map<String, DocumentReferenceFake> collectionDocuments,
List<QueryFakeAndStreamController> queries,
)?
onCollectionChanged,
}) {
collections ??= <String, CollectionReferenceFake>{};
onCollectionChanged ??= (path, collectionDocuments, queries) async {
for (final queryFakeAndController in queries) {
final futures = collectionDocuments.values.map((ref) => ref.get());
final documentSnapshots = (await Future.wait(futures))
.where(
(snapshot) {
final whereClause =
queryFakeAndController.queryFake.whereClause;
if (whereClause == null) {
return true;
}
if (whereClause.isEqualTo != null) {
return snapshot.data()![whereClause.field] ==
whereClause.isEqualTo;
} else if (whereClause.isNull != null) {
return whereClause.isNull! &&
snapshot.data()![whereClause.field] == null ||
!whereClause.isNull! &&
snapshot.data()![whereClause.field] != null;
} else {
throw UnimplementedError('Where clauses of this type '
'have not been implemented. Please log a GitHub '
'issue and hopefully contribute with a PR');
}
},
)
.map((snapshot) => QueryDocumentSnapshotFake(snapshot.data()!))
.toList();
queryFakeAndController.controller.add(
QuerySnapshotFake(documentSnapshots),
);
}
};
return FirebaseFirestoreFake(
collection: (collectionPath) {
//TODO: what is the standard behaviour in firestore?
//will it add the collection automatically?
final queriesByCollection =
<String, List<QueryFakeAndStreamController>>{};
collections!.putIfAbsent(
collectionPath,
() => CollectionReferenceFake.stateful(
collectionPath,
onChanged: (documents) {
onCollectionChanged?.call(
collectionPath,
documents,
queriesByCollection[collectionPath] ?? [],
);
},
where: (
field, {
isEqualTo,
isNotEqualTo,
isLessThan,
isLessThanOrEqualTo,
isGreaterThan,
isGreaterThanOrEqualTo,
arrayContains,
arrayContainsAny,
whereIn,
whereNotIn,
isNull,
}) {
// ignore: close_sinks
final controller = StreamController<
QuerySnapshot<Map<String, dynamic>>>.broadcast();
final queryFake = QueryFake(
snapshots: controller.stream,
whereClause: WhereClause(
field,
isEqualTo: isEqualTo,
isNotEqualTo: isNotEqualTo,
isLessThan: isLessThan,
isLessThanOrEqualTo: isLessThanOrEqualTo,
isGreaterThan: isGreaterThan,
isGreaterThanOrEqualTo: isGreaterThanOrEqualTo,
arrayContains: arrayContains,
arrayContainsAny: arrayContainsAny,
whereIn: whereIn,
whereNotIn: whereNotIn,
isNull: isNull,
),
);
if (queriesByCollection[collectionPath] == null) {
queriesByCollection[collectionPath] = [];
}
queriesByCollection[collectionPath]!.add(
QueryFakeAndStreamController(
queryFake,
controller,
),
);
return queryFake;
},
),
);
return collections[collectionPath]!;
},
);
}