diff --git a/codegen/gql_tristate_value/lib/src/value.dart b/codegen/gql_tristate_value/lib/src/value.dart index 9029a173..1a4233f5 100644 --- a/codegen/gql_tristate_value/lib/src/value.dart +++ b/codegen/gql_tristate_value/lib/src/value.dart @@ -14,6 +14,15 @@ sealed class Value { /// If the value is non-null, it will be serialized as the value. const factory Value.present(T? value) = PresentValue; + /// If the value is non-null, it will be serialized as the value. + /// If the value is null. It will not be serialized. + factory Value.absentWhenNull(T? value) { + if (value == null) { + return const AbsentValue(); + } + return Value.present(value); + } + /// Returns the value if present (no matter if null or non-null), otherwise throws a [StateError]. T? get requireValue => switch (this) { PresentValue(:final value) => value, @@ -51,4 +60,7 @@ class PresentValue extends Value { @override int get hashCode => value.hashCode; + + @override + String toString() => '$runtimeType(value: $value)'; } diff --git a/codegen/gql_tristate_value/test/value_test.dart b/codegen/gql_tristate_value/test/value_test.dart index 7cf49418..ae96e5a2 100644 --- a/codegen/gql_tristate_value/test/value_test.dart +++ b/codegen/gql_tristate_value/test/value_test.dart @@ -2,33 +2,107 @@ import 'package:gql_tristate_value/gql_tristate_value.dart'; import 'package:test/test.dart'; void main() { - test("requireValue on absent throws", () { - final absent = const AbsentValue(); + group( + 'requireValue', + () { + test('on AbsentValue throws', () { + final absent = const AbsentValue(); - expect(() => absent.requireValue, throwsA(isA())); - }); + expect(() => absent.requireValue, throwsA(isA())); + }); - test("requireValue on present returns value", () { - final present = Value.present(42); + test('on PresentValue with valuereturns value', () { + final present = Value.present(42); - expect(present.requireValue, equals(42)); - }); + expect(present.requireValue, equals(42)); + }); - test("requireValue on null returns null", () { - final nullValue = Value.present(null); + test('on PresentValue with null returns null', () { + final nullValue = Value.present(null); - expect(nullValue.requireValue, isNull); - }); + expect(nullValue.requireValue, isNull); + }); - test("valueOrNull on absent returns null", () { - final absent = const AbsentValue(); + test('on Value.ofNullable with value returns value', () { + final present = Value.absentWhenNull(42); - expect(absent.valueOrNull, isNull); - }); + expect(present.requireValue, equals(42)); + }); - test("valueOrNull on present returns value", () { - final present = Value.present(42); + test('on Value.ofNullable with null throws', () { + final nullValue = Value.absentWhenNull(null); - expect(present.valueOrNull, equals(42)); - }); + expect(() => nullValue.requireValue, throwsA(isA())); + }); + }, + ); + + group( + 'valueOrNull', + () { + test('on AbsentValue returns null', () { + final absent = const AbsentValue(); + + expect(absent.valueOrNull, isNull); + }); + + test('on PresentValue with value returns value', () { + final present = Value.present(42); + + expect(present.valueOrNull, equals(42)); + }); + + test('on Value.ofNullable with value returns value', () { + final present = Value.absentWhenNull(42); + + expect(present.valueOrNull, equals(42)); + }); + + test('on Value.ofNullable with null returns null', () { + final present = Value.absentWhenNull(null); + + expect(present.valueOrNull, isNull); + }); + }, + ); + + group( + 'isPresent', + () { + test('on AbsentValue returns false', () { + final absent = const AbsentValue(); + + expect(absent.isPresent, false); + }); + + test('on PresentValue with value returns true', () { + final present = Value.present(42); + + expect(present.isPresent, true); + }); + + test('on Value.ofNullable with value returns true', () { + final present = Value.absentWhenNull(42); + + expect(present.isPresent, true); + }); + + test('on Value.ofNullable with null returns false', () { + final present = Value.absentWhenNull(null); + + expect(present.isPresent, false); + }); + }, + ); + + group( + 'toString', + () { + test('on PresentValue', () { + final present = Value.present(42); + + expect(present.toString(), 'PresentValue(value: 42)'); + }); + }, + ); }