fix(client): do not mutate input data
the original intention is to increase test coverage on `dart:io` related,
relating to the effort to make this package compatible to web/browser
While doing this, I happen to discover a bug that we are currently mutating input data
MODIFY
packages/graphql/example/bin/main.dart
packages/graphql/example/bin/main.dart
-import 'dart:io';
+import 'dart:io' show stdout, stderr, exit;
import 'package:args/args.dart';
import 'package:graphql/client.dart';

MODIFY
packages/graphql/lib/src/cache/in_memory.dart
packages/graphql/lib/src/cache/in_memory.dart
import 'dart:async';
import 'dart:collection';
import 'dart:convert';
-import 'dart:io';
+import 'dart:io' show Directory, File, IOSink, FileSystemException;
import 'package:meta/meta.dart';
// TODO need to think about this

MODIFY
packages/graphql/lib/src/utilities/helpers.dart
packages/graphql/lib/src/utilities/helpers.dart
@@ -36,14 +36,14 @@ Map<String, dynamic> _recursivelyAddAll(
Map<String, dynamic> target,
Map<String, dynamic> source,
) {
- target = unwrapMap(target);
+ target = Map.from(unwrapMap(target));
source = unwrapMap(source);
source.forEach((String key, dynamic value) {
if (target.containsKey(key) &&
target[key] is Map &&
value != null &&
value is Map<String, dynamic>) {
- _recursivelyAddAll(
+ target[key] = _recursivelyAddAll(
target[key] as Map<String, dynamic>,
value,
);

MODIFY
packages/graphql/test/in_memory_storage_test.dart
packages/graphql/test/in_memory_storage_test.dart
@@ -57,6 +57,61 @@ void main() {
"browser": Skip("Browser does not support dart:io (see #295)")
});
+ test('.write avoids overriding a superset with a subset of a field (#155)',
+ () async {
+ final InMemoryCache cache = InMemoryCache(
+ storageProvider: () => customStorageDirectory,
+ );
+ cache.write(aKey, aData);
+
+ final Map<String, Object> anotherAData = <String, Object>{
+ 'a': <String, Object>{
+ 'key': 'val',
+ },
+ };
+ cache.write(aKey, anotherAData);
+
+ await cache.save();
+ cache.reset();
+ await cache.restore();
+ expect(
+ cache.read(aKey),
+ equals(<String, Object>{
+ 'a': {'__typename': 'A', 'key': 'val'}
+ }),
+ );
+ }, onPlatform: {
+ "browser": Skip("Browser does not support dart:io (see #295)")
+ });
+
+ test('.write does not mutate input', () async {
+ final InMemoryCache cache = InMemoryCache(
+ storageProvider: () => customStorageDirectory,
+ );
+ cache.write(aKey, aData);
+ final Map<String, Object> anotherAData = <String, Object>{
+ 'a': <String, Object>{
+ 'key': 'val',
+ },
+ };
+ cache.write(aKey, anotherAData);
+
+ expect(
+ aData,
+ equals(<String, Object>{
+ 'a': {'__typename': 'A'}
+ }),
+ );
+ expect(
+ anotherAData,
+ equals(<String, Object>{
+ 'a': {'key': 'val'}
+ }),
+ );
+ }, onPlatform: {
+ "browser": Skip("Browser does not support dart:io (see #295)")
+ });
+
test('saving concurrently wont error', () async {
final InMemoryCache cache = InMemoryCache(
storageProvider: () => customStorageDirectory,

fix(client): do not mutate input data

the original intention is to increase test coverage on `dart:io` related,
relating to the effort to make this package compatible to web/browser #295.
While doing this, I happen to discover a bug that we are currently mutating input data