Skip to content

Commit

Permalink
fix(dynamite,dynamite_runtime,nextcloud): don't deserialize integers …
Browse files Browse the repository at this point in the history
…into double

Signed-off-by: Nikolas Rimikis <leptopoda@users.noreply.github.com>
  • Loading branch information
Leptopoda committed Oct 19, 2023
1 parent 221815a commit 9845aa0
Show file tree
Hide file tree
Showing 37 changed files with 219 additions and 44 deletions.
3 changes: 2 additions & 1 deletion packages/dynamite/dynamite/lib/src/builder/imports.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ List<Spec> generateImports(final AssetId outputId) => [
Directive.import('package:built_value/serializer.dart'),
Directive.import('package:built_value/standard_json_plugin.dart'),
Directive.import('package:collection/collection.dart'),
Directive.import('package:dynamite_runtime/content_string.dart'),
Directive.import('package:dynamite_runtime/built_value.dart'),
Directive.import('package:dynamite_runtime/http_client.dart'),
Directive.import('package:dynamite_runtime/models.dart'),
Directive.import('package:dynamite_runtime/utils.dart'),
Directive.import('package:meta/meta.dart'),
Directive.import('package:universal_io/io.dart'),
Expand Down
2 changes: 1 addition & 1 deletion packages/dynamite/dynamite/lib/src/builder/serializer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ List<Spec> buildSerializer(final State state) {
const Code(').build();'),
const Code(''),
const Code(
'final Serializers _jsonSerializers = (_serializers.toBuilder()..addPlugin(StandardJsonPlugin())..addPlugin(const ContentStringPlugin())).build();',
'final Serializers _jsonSerializers = (_serializers.toBuilder()..add(DynamiteDoubleSerializer())..addPlugin(StandardJsonPlugin())..addPlugin(const ContentStringPlugin())).build();',
),
const Code('// coverage:ignore-end'),
];
Expand Down
2 changes: 2 additions & 0 deletions packages/dynamite/dynamite_runtime/lib/built_value.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export 'src/built_value/content_string_serializer.dart';
export 'src/built_value/double_serializer.dart';
1 change: 0 additions & 1 deletion packages/dynamite/dynamite_runtime/lib/content_string.dart

This file was deleted.

1 change: 0 additions & 1 deletion packages/dynamite/dynamite_runtime/lib/http_client.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export 'package:cookie_jar/cookie_jar.dart';
export 'src/dynamite_client.dart';
export 'src/http_extensions.dart';
1 change: 1 addition & 0 deletions packages/dynamite/dynamite_runtime/lib/models.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'src/models/content_string.dart';
Original file line number Diff line number Diff line change
@@ -1,22 +1,7 @@
import 'dart:convert';

import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';

part 'content_string.g.dart';

/// Json data encoded in a `String` as defined by [json-schema](https://json-schema.org/understanding-json-schema/reference/non_json_data.html#contentschema).
abstract class ContentString<T> implements Built<ContentString<T>, ContentStringBuilder<T>> {
/// Creates a new content `String`.
factory ContentString([final void Function(ContentStringBuilder<T>)? b]) = _$ContentString<T>;
const ContentString._();

/// The decoded value of the content `String`.
T get content;

/// The serializer for a content `String`.
static Serializer<ContentString<Object?>> get serializer => _$contentStringSerializer;
}
import 'package:dynamite_runtime/src/models/content_string.dart';

/// Serialization plugin for decoding [ContentString]s.
///
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'package:built_collection/built_collection.dart';
import 'package:built_value/serializer.dart';

/// A built_value serializer for `double` values that does not accept integers.
class DynamiteDoubleSerializer implements PrimitiveSerializer<double> {
// Constant names match those in [double].
static const String _nan = 'NaN';
static const String _infinity = 'INF';
static const String _negativeInfinity = '-INF';

@override
final Iterable<Type> types = BuiltList<Type>([double]);

@override
final String wireName = 'double';

@override
Object serialize(
final Serializers serializers,
final double aDouble, {
final FullType specifiedType = FullType.unspecified,
}) {
if (aDouble.isNaN) {
return _nan;
} else if (aDouble.isInfinite) {
return aDouble.isNegative ? _negativeInfinity : _infinity;
} else {
return aDouble;
}
}

@override
double deserialize(
final Serializers serializers,
final Object serialized, {
final FullType specifiedType = FullType.unspecified,
}) {
if (serialized == _nan) {
return double.nan;
} else if (serialized == _negativeInfinity) {
return double.negativeInfinity;
} else if (serialized == _infinity) {
return double.infinity;
} else {
return serialized as double;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';

part 'content_string.g.dart';

/// Json data encoded in a `String` as defined by [json-schema](https://json-schema.org/understanding-json-schema/reference/non_json_data.html#contentschema).
abstract class ContentString<T> implements Built<ContentString<T>, ContentStringBuilder<T>> {
/// Creates a new content `String`.
factory ContentString([final void Function(ContentStringBuilder<T>)? b]) = _$ContentString<T>;
const ContentString._();

/// The decoded value of the content `String`.
T get content;

/// The serializer for a content `String`.
static Serializer<ContentString<Object?>> get serializer => _$contentStringSerializer;
}
1 change: 1 addition & 0 deletions packages/dynamite/dynamite_runtime/lib/utils.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export 'src/http_extensions.dart';
export 'src/string_checker.dart';
export 'src/uri.dart';
2 changes: 1 addition & 1 deletion packages/dynamite/dynamite_runtime/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ environment:
sdk: '>=3.1.0 <4.0.0'

dependencies:
built_collection: ^5.0.0
built_value: ^8.0.1
cookie_jar: ^4.0.0
meta: ^1.0.0
universal_io: ^2.0.0

dev_dependencies:
build_runner: ^2.4.6
built_collection: ^5.1.1
built_value_generator: ^8.6.3
neon_lints:
git:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import 'dart:convert';
import 'package:built_collection/built_collection.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:dynamite_runtime/content_string.dart';
import 'package:dynamite_runtime/built_value.dart';
import 'package:dynamite_runtime/models.dart';
import 'package:test/test.dart';

part 'content_string_test.g.dart';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// ignore_for_file: avoid_redundant_argument_values

import 'dart:convert';

import 'package:built_value/serializer.dart';
import 'package:dynamite_runtime/built_value.dart';
import 'package:test/test.dart';

void main() {
final serializers = (Serializers().toBuilder()..add(DynamiteDoubleSerializer())).build();

group('double with known specifiedType', () {
const data = 3.141592653589793;
const serialized = data;
const specifiedType = FullType(double);

test('can be serialized', () {
expect(serializers.serialize(data, specifiedType: specifiedType), serialized);
});

test('can be deserialized', () {
expect(serializers.deserialize(serialized, specifiedType: specifiedType), data);
});
});

group('double with unknown specifiedType', () {
const data = 3.141592653589793;
final serialized = json.decode(json.encode(['double', data])) as Object;
const specifiedType = FullType.unspecified;

test('can be serialized', () {
expect(serializers.serialize(data, specifiedType: specifiedType), serialized);
});

test('can be deserialized', () {
expect(serializers.deserialize(serialized, specifiedType: specifiedType), data);
});
});

group('integer with known specifiedType', () {
const data = 3;
const serialized = data;
const specifiedType = FullType(double);

test('can not be deserialized', () {
expect(
() => serializers.deserialize(serialized, specifiedType: specifiedType),
throwsA(isA<DeserializationError>()),
);
});
});

group('double with NaN value', () {
const data = double.nan;
const serialized = 'NaN';
const specifiedType = FullType(double);

test('can be serialized', () {
expect(serializers.serialize(data, specifiedType: specifiedType), serialized);
});

test('can be deserialized', () {
// Compare using toString as NaN != NaN.
expect(serializers.deserialize(serialized, specifiedType: specifiedType).toString(), data.toString());
});
});

group('double with -INF value', () {
const data = double.negativeInfinity;
const serialized = '-INF';
const specifiedType = FullType(double);

test('can be serialized', () {
expect(serializers.serialize(data, specifiedType: specifiedType), serialized);
});

test('can be deserialized', () {
expect(serializers.deserialize(serialized, specifiedType: specifiedType), data);
});
});

group('double with INF value', () {
const data = double.infinity;
const serialized = 'INF';
const specifiedType = FullType(double);

test('can be serialized', () {
expect(serializers.serialize(data, specifiedType: specifiedType), serialized);
});

test('can be deserialized', () {
expect(serializers.deserialize(serialized, specifiedType: specifiedType), data);
});
});
}
2 changes: 1 addition & 1 deletion packages/nextcloud/lib/nextcloud.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export 'package:dynamite_runtime/content_string.dart';
export 'package:dynamite_runtime/http_client.dart'
show CookieJar, DynamiteApiException, DynamiteRawResponse, DynamiteResponse;
export 'package:dynamite_runtime/models.dart';

export 'ids.dart';
export 'src/client.dart';
Expand Down
3 changes: 2 additions & 1 deletion packages/nextcloud/lib/src/api/comments.openapi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:dynamite_runtime/content_string.dart';
import 'package:dynamite_runtime/built_value.dart';
import 'package:dynamite_runtime/http_client.dart';

part 'comments.openapi.g.dart';
Expand Down Expand Up @@ -88,6 +88,7 @@ final Serializers _serializers = (Serializers().toBuilder()
.build();

final Serializers _jsonSerializers = (_serializers.toBuilder()
..add(DynamiteDoubleSerializer())
..addPlugin(StandardJsonPlugin())
..addPlugin(const ContentStringPlugin()))
.build();
Expand Down
4 changes: 3 additions & 1 deletion packages/nextcloud/lib/src/api/core.openapi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:collection/collection.dart';
import 'package:dynamite_runtime/content_string.dart';
import 'package:dynamite_runtime/built_value.dart';
import 'package:dynamite_runtime/http_client.dart';
import 'package:dynamite_runtime/models.dart';
import 'package:meta/meta.dart';
import 'package:universal_io/io.dart';

Expand Down Expand Up @@ -10401,6 +10402,7 @@ final Serializers _serializers = (Serializers().toBuilder()
.build();

final Serializers _jsonSerializers = (_serializers.toBuilder()
..add(DynamiteDoubleSerializer())
..addPlugin(StandardJsonPlugin())
..addPlugin(const ContentStringPlugin()))
.build();
Expand Down
4 changes: 3 additions & 1 deletion packages/nextcloud/lib/src/api/dashboard.openapi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:collection/collection.dart';
import 'package:dynamite_runtime/content_string.dart';
import 'package:dynamite_runtime/built_value.dart';
import 'package:dynamite_runtime/http_client.dart';
import 'package:dynamite_runtime/models.dart';
import 'package:meta/meta.dart';
import 'package:universal_io/io.dart';

Expand Down Expand Up @@ -758,6 +759,7 @@ final Serializers _serializers = (Serializers().toBuilder()
.build();

final Serializers _jsonSerializers = (_serializers.toBuilder()
..add(DynamiteDoubleSerializer())
..addPlugin(StandardJsonPlugin())
..addPlugin(const ContentStringPlugin()))
.build();
Expand Down
3 changes: 2 additions & 1 deletion packages/nextcloud/lib/src/api/dav.openapi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:collection/collection.dart';
import 'package:dynamite_runtime/content_string.dart';
import 'package:dynamite_runtime/built_value.dart';
import 'package:dynamite_runtime/http_client.dart';
import 'package:meta/meta.dart';
import 'package:universal_io/io.dart';
Expand Down Expand Up @@ -334,6 +334,7 @@ final Serializers _serializers = (Serializers().toBuilder()
.build();

final Serializers _jsonSerializers = (_serializers.toBuilder()
..add(DynamiteDoubleSerializer())
..addPlugin(StandardJsonPlugin())
..addPlugin(const ContentStringPlugin()))
.build();
Expand Down
3 changes: 2 additions & 1 deletion packages/nextcloud/lib/src/api/files.openapi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:collection/collection.dart';
import 'package:dynamite_runtime/content_string.dart';
import 'package:dynamite_runtime/built_value.dart';
import 'package:dynamite_runtime/http_client.dart';
import 'package:dynamite_runtime/utils.dart';
import 'package:meta/meta.dart';
Expand Down Expand Up @@ -2823,6 +2823,7 @@ final Serializers _serializers = (Serializers().toBuilder()
.build();

final Serializers _jsonSerializers = (_serializers.toBuilder()
..add(DynamiteDoubleSerializer())
..addPlugin(StandardJsonPlugin())
..addPlugin(const ContentStringPlugin()))
.build();
Expand Down
3 changes: 2 additions & 1 deletion packages/nextcloud/lib/src/api/files_external.openapi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:collection/collection.dart';
import 'package:dynamite_runtime/content_string.dart';
import 'package:dynamite_runtime/built_value.dart';
import 'package:dynamite_runtime/http_client.dart';
import 'package:meta/meta.dart';
import 'package:universal_io/io.dart';
Expand Down Expand Up @@ -360,6 +360,7 @@ final Serializers _serializers = (Serializers().toBuilder()
.build();

final Serializers _jsonSerializers = (_serializers.toBuilder()
..add(DynamiteDoubleSerializer())
..addPlugin(StandardJsonPlugin())
..addPlugin(const ContentStringPlugin()))
.build();
Expand Down
3 changes: 2 additions & 1 deletion packages/nextcloud/lib/src/api/files_reminders.openapi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:collection/collection.dart';
import 'package:dynamite_runtime/content_string.dart';
import 'package:dynamite_runtime/built_value.dart';
import 'package:dynamite_runtime/http_client.dart';
import 'package:dynamite_runtime/utils.dart';
import 'package:meta/meta.dart';
Expand Down Expand Up @@ -609,6 +609,7 @@ final Serializers _serializers = (Serializers().toBuilder()
.build();

final Serializers _jsonSerializers = (_serializers.toBuilder()
..add(DynamiteDoubleSerializer())
..addPlugin(StandardJsonPlugin())
..addPlugin(const ContentStringPlugin()))
.build();
Expand Down
4 changes: 3 additions & 1 deletion packages/nextcloud/lib/src/api/files_sharing.openapi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:collection/collection.dart';
import 'package:dynamite_runtime/content_string.dart';
import 'package:dynamite_runtime/built_value.dart';
import 'package:dynamite_runtime/http_client.dart';
import 'package:dynamite_runtime/models.dart';
import 'package:meta/meta.dart';
import 'package:universal_io/io.dart';

Expand Down Expand Up @@ -5372,6 +5373,7 @@ final Serializers _serializers = (Serializers().toBuilder()
.build();

final Serializers _jsonSerializers = (_serializers.toBuilder()
..add(DynamiteDoubleSerializer())
..addPlugin(StandardJsonPlugin())
..addPlugin(const ContentStringPlugin()))
.build();
Expand Down
Loading

0 comments on commit 9845aa0

Please sign in to comment.