From 53feedafd0973054c546aac3ed2f7fc082ded43d Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Sat, 12 Oct 2024 12:01:03 +0100 Subject: [PATCH 01/11] feat: Support transient identities and traits --- lib/src/model/feature.g.dart | 22 ++++++------- lib/src/model/flag.g.dart | 20 ++++++------ lib/src/model/flags_and_traits.g.dart | 19 ++++++----- lib/src/model/identity.dart | 8 +++-- lib/src/model/identity.g.dart | 25 ++++++++++----- lib/src/model/trait.dart | 3 ++ lib/src/model/trait.g.dart | 45 ++++++++++++++++----------- pubspec.yaml | 12 +++---- test/models/identity_test.dart | 12 +++++-- test/models/trait_test.dart | 35 +++++++++++++++++++++ 10 files changed, 132 insertions(+), 69 deletions(-) diff --git a/lib/src/model/feature.g.dart b/lib/src/model/feature.g.dart index 2f84d89..f6dcbdf 100644 --- a/lib/src/model/feature.g.dart +++ b/lib/src/model/feature.g.dart @@ -8,18 +8,16 @@ part of 'feature.dart'; // JsonSerializableGenerator // ************************************************************************** -Feature _$FeatureFromJson(Map json) { - return Feature( - id: json['id'] as int?, - name: json['name'] as String, - createdDate: json['created_date'] == null - ? null - : DateTime.parse(json['created_date'] as String), - initialValue: stringFromJson(json['initial_value']), - defaultValue: json['default_enabled'] as bool?, - description: json['description'] as String?, - ); -} +Feature _$FeatureFromJson(Map json) => Feature( + id: (json['id'] as num?)?.toInt(), + name: json['name'] as String, + createdDate: json['created_date'] == null + ? null + : DateTime.parse(json['created_date'] as String), + initialValue: stringFromJson(json['initial_value']), + defaultValue: json['default_enabled'] as bool?, + description: json['description'] as String?, + ); Map _$FeatureToJson(Feature instance) => { 'id': instance.id, diff --git a/lib/src/model/flag.g.dart b/lib/src/model/flag.g.dart index 954b375..ddfecd9 100644 --- a/lib/src/model/flag.g.dart +++ b/lib/src/model/flag.g.dart @@ -8,17 +8,15 @@ part of 'flag.dart'; // JsonSerializableGenerator // ************************************************************************** -Flag _$FlagFromJson(Map json) { - return Flag( - id: json['id'] as int?, - feature: Feature.fromJson(json['feature'] as Map), - stateValue: stringFromJson(json['feature_state_value']), - enabled: json['enabled'] as bool?, - environment: json['environment'] as int?, - identity: json['identity'] as int?, - featureSegment: json['feature_segment'] as int?, - ); -} +Flag _$FlagFromJson(Map json) => Flag( + id: (json['id'] as num?)?.toInt(), + feature: Feature.fromJson(json['feature'] as Map), + stateValue: stringFromJson(json['feature_state_value']), + enabled: json['enabled'] as bool?, + environment: (json['environment'] as num?)?.toInt(), + identity: (json['identity'] as num?)?.toInt(), + featureSegment: (json['feature_segment'] as num?)?.toInt(), + ); Map _$FlagToJson(Flag instance) => { 'id': instance.id, diff --git a/lib/src/model/flags_and_traits.g.dart b/lib/src/model/flags_and_traits.g.dart index c80c15c..c454eef 100644 --- a/lib/src/model/flags_and_traits.g.dart +++ b/lib/src/model/flags_and_traits.g.dart @@ -8,16 +8,15 @@ part of 'flags_and_traits.dart'; // JsonSerializableGenerator // ************************************************************************** -FlagsAndTraits _$FlagsAndTraitsFromJson(Map json) { - return FlagsAndTraits( - flags: (json['flags'] as List?) - ?.map((e) => Flag.fromJson(e as Map)) - .toList(), - traits: (json['traits'] as List?) - ?.map((e) => Trait.fromJson(e as Map)) - .toList(), - ); -} +FlagsAndTraits _$FlagsAndTraitsFromJson(Map json) => + FlagsAndTraits( + flags: (json['flags'] as List?) + ?.map((e) => Flag.fromJson(e as Map)) + .toList(), + traits: (json['traits'] as List?) + ?.map((e) => Trait.fromJson(e as Map)) + .toList(), + ); Map _$FlagsAndTraitsToJson(FlagsAndTraits instance) => { diff --git a/lib/src/model/identity.dart b/lib/src/model/identity.dart index f2161c5..d793d0e 100644 --- a/lib/src/model/identity.dart +++ b/lib/src/model/identity.dart @@ -6,8 +6,12 @@ part 'identity.g.dart'; /// Personalized user @JsonSerializable() class Identity { + @JsonKey(includeIfNull: false) + final bool? transient; final String identifier; + const Identity({ + this.transient, required this.identifier, }); @@ -16,6 +20,6 @@ class Identity { Map toJson() => _$IdentityToJson(this); String asString() => jsonEncode(toJson()); - Identity copyWith({String? identifier}) => - Identity(identifier: identifier ?? this.identifier); + Identity copyWith({String? identifier, bool? transient}) => + Identity(identifier: identifier ?? this.identifier, transient: transient ?? this.transient); } diff --git a/lib/src/model/identity.g.dart b/lib/src/model/identity.g.dart index af98d91..f9342ae 100644 --- a/lib/src/model/identity.g.dart +++ b/lib/src/model/identity.g.dart @@ -8,12 +8,21 @@ part of 'identity.dart'; // JsonSerializableGenerator // ************************************************************************** -Identity _$IdentityFromJson(Map json) { - return Identity( - identifier: json['identifier'] as String, - ); -} +Identity _$IdentityFromJson(Map json) => Identity( + transient: json['transient'] as bool?, + identifier: json['identifier'] as String, + ); + +Map _$IdentityToJson(Identity instance) { + final val = {}; -Map _$IdentityToJson(Identity instance) => { - 'identifier': instance.identifier, - }; + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } + + writeNotNull('transient', instance.transient); + val['identifier'] = instance.identifier; + return val; +} diff --git a/lib/src/model/trait.dart b/lib/src/model/trait.dart index 73fef60..1aaeb52 100644 --- a/lib/src/model/trait.dart +++ b/lib/src/model/trait.dart @@ -8,6 +8,8 @@ part 'trait.g.dart'; @JsonSerializable() class Trait { final int? id; + @JsonKey(includeIfNull: false) + final bool? transient; @JsonKey(name: 'trait_key') final String key; @JsonKey(name: 'trait_value', fromJson: _fromJson, toJson: _toJson) @@ -15,6 +17,7 @@ class Trait { Trait({ this.id, + this.transient, required this.key, required this.value, }); diff --git a/lib/src/model/trait.g.dart b/lib/src/model/trait.g.dart index af18cc7..530464a 100644 --- a/lib/src/model/trait.g.dart +++ b/lib/src/model/trait.g.dart @@ -8,28 +8,37 @@ part of 'trait.dart'; // JsonSerializableGenerator // ************************************************************************** -Trait _$TraitFromJson(Map json) { - return Trait( - id: json['id'] as int?, - key: json['trait_key'] as String, - value: Trait._fromJson(json['trait_value']), - ); -} +Trait _$TraitFromJson(Map json) => Trait( + id: (json['id'] as num?)?.toInt(), + transient: json['transient'] as bool?, + key: json['trait_key'] as String, + value: Trait._fromJson(json['trait_value']), + ); -Map _$TraitToJson(Trait instance) => { - 'id': instance.id, - 'trait_key': instance.key, - 'trait_value': Trait._toJson(instance.value), - }; +Map _$TraitToJson(Trait instance) { + final val = { + 'id': instance.id, + }; -TraitWithIdentity _$TraitWithIdentityFromJson(Map json) { - return TraitWithIdentity( - identity: Identity.fromJson(json['identity'] as Map), - key: json['trait_key'] as String, - value: TraitWithIdentity._fromJson(json['trait_value']), - ); + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } + + writeNotNull('transient', instance.transient); + val['trait_key'] = instance.key; + val['trait_value'] = Trait._toJson(instance.value); + return val; } +TraitWithIdentity _$TraitWithIdentityFromJson(Map json) => + TraitWithIdentity( + identity: Identity.fromJson(json['identity'] as Map), + key: json['trait_key'] as String, + value: TraitWithIdentity._fromJson(json['trait_value']), + ); + Map _$TraitWithIdentityToJson(TraitWithIdentity instance) => { 'identity': instance.identity.toJson(), diff --git a/pubspec.yaml b/pubspec.yaml index 3a78029..54c14c3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: >- Core Package of Flutter Client SDK for https://www.flagsmith.com/, Flagsmith is 100% Open Source. Host yourself or let us take care of the hosting. -version: 3.0.0 +version: 3.1.0 homepage: https://github.com/Flagsmith/flagsmith-flutter-core repository: https://github.com/Flagsmith/flagsmith-flutter-core issue_tracker: https://github.com/Flagsmith/flagsmith-flutter-core/issues @@ -14,13 +14,13 @@ environment: dependencies: crypto: ^3.0.1 encrypt: ^5.0.1 - rxdart: ^0.27.5 + rxdart: ^0.28.0 json_annotation: ^4.0.1 collection: ^1.15.0 dev_dependencies: - flutter_lints: ^1.0.0 - test: ">=1.16.0 <=1.17.12" - http_mock_adapter: ^0.3.2 + flutter_lints: ^5.0.0 + test: ^1.25.8 + http_mock_adapter: ^0.6.1 mockito: ^5.0.15 - json_serializable: ^4.1.3 + json_serializable: ^6.8.0 build_runner: ^2.1.2 diff --git a/test/models/identity_test.dart b/test/models/identity_test.dart index 487f6d3..ee8af8a 100644 --- a/test/models/identity_test.dart +++ b/test/models/identity_test.dart @@ -6,13 +6,20 @@ import 'package:test/test.dart'; void main() { const identityId = '123-456-789'; const identityJson = r'''{"identifier":"123-456-789"}'''; + const transientIdentityJson = r'''{"identifier":"123-456-789","transient":true}'''; final decodedIdentityJson = jsonDecode(identityJson) as Map; + final decodedTransientIdentityJson = jsonDecode(transientIdentityJson) as Map; // final malformedIdentityJson = '''{"identifier_bad_guy":"$identityId"}'''; group('[Identity]', () { - test('When identy response converted then success', () { + test('When identity response converted then success', () { final identity = Identity.fromJson(decodedIdentityJson); expect(identity.identifier, identityId); }); + test('When transient identity response converted then success', () { + final identity = Identity.fromJson(decodedTransientIdentityJson); + expect(identity.identifier, identityId); + expect(identity.transient, true); + }); }); group('[Identity] - copyWith', () { @@ -20,8 +27,9 @@ void main() { final identity = Identity.fromJson(decodedIdentityJson); expect(identity.identifier, identityId); - final updated = identity.copyWith(identifier: 'newOne'); + final updated = identity.copyWith(identifier: 'newOne', transient: true); expect(updated.identifier, 'newOne'); + expect(updated.transient, true); expect(identity.hashCode, isNot(updated.hashCode)); }); test('When identity not updated then success', () { diff --git a/test/models/trait_test.dart b/test/models/trait_test.dart index 48a5045..f248ef8 100644 --- a/test/models/trait_test.dart +++ b/test/models/trait_test.dart @@ -33,6 +33,14 @@ void main() { }'''; final decodedTraitDoubleValue = jsonDecode(traitDoubleValue) as Map; + const transientTraitValue = '''{ + "id": 12, + "trait_key": "trait_key", + "trait_value": "transient", + "transient": true + }'''; + final decodedTransientTraitValue = + jsonDecode(transientTraitValue) as Map; group('[Trait] - basic tests', () { test('When trait parsed then success', () { @@ -56,6 +64,14 @@ void main() { }); test('When trait parsed with double value then success', () { + final trait = Trait.fromJson(decodedTransientTraitValue); + expect(trait.id, 12); + expect(trait.key, 'trait_key'); + expect(trait.value, 'transient'); + expect(trait.transient, true); + }); + + test('When transient trait parsed then success', () { final trait = Trait.fromJson(decodedTraitDoubleValue); expect(trait.id, 12); expect(trait.key, 'trait_key'); @@ -185,5 +201,24 @@ void main() { expect(mapped['trait_key'], 'trait_key'); expect(mapped['trait_value'], true); }); + + test( + 'When transient trait converted to Map then success', + () { + final trait = Trait( + id: 12, + key: 'trait_key', + value: 'transient', + transient: true, + ); + + final mapped = trait.toJson(); + + expect(mapped, isNotNull); + expect(mapped['id'], 12); + expect(mapped['trait_key'], 'trait_key'); + expect(mapped['trait_value'], 'transient'); + expect(mapped['transient'], true); + }); }); } From 1c766b4b48f40cf90c930a04730b304f40a6e74b Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Sun, 13 Oct 2024 23:29:35 +0100 Subject: [PATCH 02/11] bump actions --- .github/workflows/dry_run_workflow.yml | 17 ++++++++++------- .github/workflows/publish_main.yml | 8 ++++---- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/workflows/dry_run_workflow.yml b/.github/workflows/dry_run_workflow.yml index 47bd2aa..2f12b4c 100644 --- a/.github/workflows/dry_run_workflow.yml +++ b/.github/workflows/dry_run_workflow.yml @@ -1,15 +1,18 @@ name: Analyze and Test on: [push] +env: + FLUTTER_VERSION: 2.x + jobs: analyze: runs-on: ubuntu-latest name: Dart Analyze steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: - flutter-version: '2.x' + flutter-version: ${{ env.FLUTTER_VERSION }} channel: 'any' - run: flutter pub get - run: flutter analyze @@ -18,10 +21,10 @@ jobs: runs-on: ubuntu-latest name: Flutter Test steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: - flutter-version: '2.x' + flutter-version: ${{ env.FLUTTER_VERSION }} channel: 'any' - run: flutter pub get @@ -32,7 +35,7 @@ jobs: name: Dart package score steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: axel-op/dart-package-analyzer@v3 with: githubToken: ${{ secrets.GITHUB_TOKEN }} @@ -42,10 +45,10 @@ jobs: name: Dart Publish Package Test needs: tests steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: - flutter-version: '2.x' + flutter-version: ${{ env.FLUTTER_VERSION }} channel: 'any' - run: flutter pub publish --dry-run diff --git a/.github/workflows/publish_main.yml b/.github/workflows/publish_main.yml index 48a2113..66cfe98 100644 --- a/.github/workflows/publish_main.yml +++ b/.github/workflows/publish_main.yml @@ -10,8 +10,8 @@ jobs: name: Dart Analyze steps: - - uses: actions/checkout@v2 - - uses: subosito/flutter-action@v1 + - uses: actions/checkout@v4 + - uses: subosito/flutter-action@v2 - run: flutter pub get - run: flutter analyze score: @@ -19,7 +19,7 @@ jobs: name: Dart package score steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: axel-op/dart-package-analyzer@v3 with: githubToken: ${{ secrets.GITHUB_TOKEN }} @@ -31,7 +31,7 @@ jobs: name: Dart Publish Package needs: analyze steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Setup credentials run: | mkdir -p ~/.pub-cache From 914e14143c36532f4950cc7d91cd4c5d79b92685 Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Mon, 14 Oct 2024 12:41:07 +0100 Subject: [PATCH 03/11] bump Flutter --- .github/workflows/dry_run_workflow.yml | 9 +++------ pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/dry_run_workflow.yml b/.github/workflows/dry_run_workflow.yml index 2f12b4c..e4dc60e 100644 --- a/.github/workflows/dry_run_workflow.yml +++ b/.github/workflows/dry_run_workflow.yml @@ -1,9 +1,6 @@ name: Analyze and Test on: [push] -env: - FLUTTER_VERSION: 2.x - jobs: analyze: runs-on: ubuntu-latest @@ -12,7 +9,7 @@ jobs: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ env.FLUTTER_VERSION }} + flutter-version-file: pubspec.yaml channel: 'any' - run: flutter pub get - run: flutter analyze @@ -24,7 +21,7 @@ jobs: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ env.FLUTTER_VERSION }} + flutter-version-file: pubspec.yaml channel: 'any' - run: flutter pub get @@ -48,7 +45,7 @@ jobs: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ env.FLUTTER_VERSION }} + flutter-version-file: pubspec.yaml channel: 'any' - run: flutter pub publish --dry-run diff --git a/pubspec.yaml b/pubspec.yaml index 54c14c3..a7658c5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,7 +9,7 @@ repository: https://github.com/Flagsmith/flagsmith-flutter-core issue_tracker: https://github.com/Flagsmith/flagsmith-flutter-core/issues environment: - sdk: ">=2.13.0 <3.0.0" + sdk: ">=3.0.0" dependencies: crypto: ^3.0.1 From b08af407b3f0b18d1b3f26a8ae37435ee0407a54 Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Mon, 14 Oct 2024 12:53:02 +0100 Subject: [PATCH 04/11] pin flutter version --- pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/pubspec.yaml b/pubspec.yaml index a7658c5..00d042f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,6 +10,7 @@ issue_tracker: https://github.com/Flagsmith/flagsmith-flutter-core/issues environment: sdk: ">=3.0.0" + flutter: 3.24.3 dependencies: crypto: ^3.0.1 From 91f955fa45173a649390e403357547fbe1eb9b2c Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Mon, 14 Oct 2024 12:55:56 +0100 Subject: [PATCH 05/11] dart fix --apply --- lib/src/storage_provider.dart | 4 ++-- test/flagsmith_core_test.dart | 24 ++++++++++++------------ test/models/flag_test.dart | 32 ++++++++++++++++---------------- test/storage_reactive_test.dart | 10 +++++----- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/lib/src/storage_provider.dart b/lib/src/storage_provider.dart index d3f15ff..065d6bc 100644 --- a/lib/src/storage_provider.dart +++ b/lib/src/storage_provider.dart @@ -88,8 +88,8 @@ class StorageProvider with SecureStorage { Future saveAll(List items) async { for (var item in items) { - final _current = await read(item.key); - if (_current != null) { + final current = await read(item.key); + if (current != null) { await update(item.key, item); } else { await create(item.key, item); diff --git a/test/flagsmith_core_test.dart b/test/flagsmith_core_test.dart index 5e394f7..c653762 100644 --- a/test/flagsmith_core_test.dart +++ b/test/flagsmith_core_test.dart @@ -43,20 +43,20 @@ void main() { expect(items, isEmpty); }); test('Create a flag', () async { - final _created = await storageProvider.create( + final created = await storageProvider.create( 'test_feature', Flag.seed('test_feature', enabled: false)); - expect(_created, isTrue); + expect(created, isTrue); }); test('Save all flags', () async { - final _created = await storageProvider.saveAll([ + final created = await storageProvider.saveAll([ Flag.seed('test_feature_a', enabled: false), Flag.seed('test_feature_b', enabled: true) ]); - expect(_created, isTrue); - final _all = await storageProvider.getAll(); - expect(_all, isNotEmpty); + expect(created, isTrue); + final all0 = await storageProvider.getAll(); + expect(all0, isNotEmpty); expect( - _all, + all0, const TypeMatcher>().having( (p0) => p0 .firstWhereOrNull((element) => element.key == 'test_feature_a'), @@ -65,15 +65,15 @@ void main() { }); test('Update all flags', () async { - final _created = await storageProvider.saveAll([ + final created = await storageProvider.saveAll([ Flag.seed('test_feature_a', enabled: false), Flag.seed('test_feature_b', enabled: true) ]); - expect(_created, isTrue); - final _all = await storageProvider.getAll(); - expect(_all, isNotEmpty); + expect(created, isTrue); + final all0 = await storageProvider.getAll(); + expect(all0, isNotEmpty); expect( - _all, + all0, const TypeMatcher>().having( (p0) => p0 .firstWhereOrNull((element) => element.key == 'test_feature_a'), diff --git a/test/models/flag_test.dart b/test/models/flag_test.dart index b9024fe..e2a4387 100644 --- a/test/models/flag_test.dart +++ b/test/models/flag_test.dart @@ -44,28 +44,28 @@ void main() { expect(flag.feature.description, isNotNull); }); test('When feature successfuly parsed', () async { - final _feature = + final feature = Feature.fromJson(jsonDecode(featureValue) as Map); - expect(_feature, isNotNull); - expect(_feature.id, 2); + expect(feature, isNotNull); + expect(feature.id, 2); }); test('When flag successfuly parsed', () { var flag = Flag.fromJson(jsonDecode(testValue) as Map); - final _flag = flag.asString(); - expect(_flag, isA()); - expect(_flag, isNotNull); - expect(_flag, isNotEmpty); + final flag0 = flag.asString(); + expect(flag0, isA()); + expect(flag0, isNotNull); + expect(flag0, isNotEmpty); }); test('When flag value successfuly updated', () { var flag = Flag.fromJson(jsonDecode(testValue) as Map); - final _feature = flag.feature.copyWith(initialValue: '12'); - final _flag = flag.copyWith(feature: _feature); + final feature = flag.feature.copyWith(initialValue: '12'); + final flag0 = flag.copyWith(feature: feature); expect(flag.feature.initialValue, '10'); - expect(_flag.feature.initialValue, '12'); - expect(flag.feature.initialValue, isNot(_flag.feature.initialValue)); + expect(flag0.feature.initialValue, '12'); + expect(flag.feature.initialValue, isNot(flag0.feature.initialValue)); }); test('When flag seed state is enabled', () { @@ -100,13 +100,13 @@ void main() { expect(identity.flags, isNotEmpty); expect(identity.traits, isNotEmpty); - final _converted = identity.toJson(); - expect(_converted, isNotNull); - expect(_converted, isNotEmpty); + final converted = identity.toJson(); + expect(converted, isNotNull); + expect(converted, isNotEmpty); - final _copiedIdentity = identity.copyWith(flags: [], traits: []); + final copiedIdentity = identity.copyWith(flags: [], traits: []); expect( - _copiedIdentity, + copiedIdentity, const TypeMatcher() .having((e) => e.flags, 'flags are empty', isEmpty) .having((e) => e.traits, 'traits are empty', isEmpty)); diff --git a/test/storage_reactive_test.dart b/test/storage_reactive_test.dart index 1a1ddcf..0598cb2 100644 --- a/test/storage_reactive_test.dart +++ b/test/storage_reactive_test.dart @@ -21,16 +21,16 @@ void main() { const TypeMatcher() .having((s) => s.enabled, '$myFeature is not enabled', false), ])); - final _toggled = await store.togggleFeature(myFeature); - expect(_toggled, isTrue); + final toggled = await store.togggleFeature(myFeature); + expect(toggled, isTrue); }); test('Subject value changed when flag was changed.', () async { await store.clear(); await store.seed(items: seeds); - final _feature = await store.read(myFeature); - expect(_feature, isNotNull); - expect(_feature!.enabled, isTrue); + final feature = await store.read(myFeature); + expect(feature, isNotNull); + expect(feature!.enabled, isTrue); expect(store.subject(myFeature)?.stream.valueOrNull?.enabled, true); expect( From b653b01ccdce219f9e1e8b2481b0c15b108e006c Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Mon, 14 Oct 2024 12:57:28 +0100 Subject: [PATCH 06/11] fix unnecessary_library_name --- lib/flagsmith_flutter_core.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/flagsmith_flutter_core.dart b/lib/flagsmith_flutter_core.dart index ee807b6..558ef1c 100644 --- a/lib/flagsmith_flutter_core.dart +++ b/lib/flagsmith_flutter_core.dart @@ -1,5 +1,3 @@ -library flagsmith_flutter_core; - export 'src/extensions/converters.dart'; export 'src/model/index.dart'; export 'src/storage/in_memory_storage.dart'; From 03a7fdbaa54b2da31337121bd7023c27ecbed816 Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Mon, 14 Oct 2024 13:04:28 +0100 Subject: [PATCH 07/11] use env --- .github/workflows/dry_run_workflow.yml | 14 ++++++-------- pubspec.yaml | 3 +-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/dry_run_workflow.yml b/.github/workflows/dry_run_workflow.yml index e4dc60e..419d9fd 100644 --- a/.github/workflows/dry_run_workflow.yml +++ b/.github/workflows/dry_run_workflow.yml @@ -1,6 +1,9 @@ name: Analyze and Test on: [push] +env: + FLUTTER_VERSION: 3.x + jobs: analyze: runs-on: ubuntu-latest @@ -9,8 +12,7 @@ jobs: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: - flutter-version-file: pubspec.yaml - channel: 'any' + flutter-version: ${{ env.FLUTTER_VERSION }} - run: flutter pub get - run: flutter analyze @@ -21,9 +23,7 @@ jobs: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: - flutter-version-file: pubspec.yaml - channel: 'any' - + flutter-version: ${{ env.FLUTTER_VERSION }} - run: flutter pub get - run: flutter pub test @@ -45,7 +45,5 @@ jobs: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: - flutter-version-file: pubspec.yaml - channel: 'any' - + flutter-version: ${{ env.FLUTTER_VERSION }} - run: flutter pub publish --dry-run diff --git a/pubspec.yaml b/pubspec.yaml index 00d042f..b233788 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,8 +9,7 @@ repository: https://github.com/Flagsmith/flagsmith-flutter-core issue_tracker: https://github.com/Flagsmith/flagsmith-flutter-core/issues environment: - sdk: ">=3.0.0" - flutter: 3.24.3 + sdk: ^3.0.0 dependencies: crypto: ^3.0.1 From 23a3ce7f4f0a94c93fef115e485278039849beb4 Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Mon, 14 Oct 2024 13:25:22 +0100 Subject: [PATCH 08/11] bump library version, update changelog --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89474b6..220e170 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 4.0.0 +* Drop Flutter 2 support +* feat: Support transient identities and traits + +## 3.1.0 +* Added a null check on enabled field of flag + ## 3.0.0 * trait/value: Add support for int,float, bool and string diff --git a/pubspec.yaml b/pubspec.yaml index b233788..1ca8146 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: >- Core Package of Flutter Client SDK for https://www.flagsmith.com/, Flagsmith is 100% Open Source. Host yourself or let us take care of the hosting. -version: 3.1.0 +version: 4.0.0 homepage: https://github.com/Flagsmith/flagsmith-flutter-core repository: https://github.com/Flagsmith/flagsmith-flutter-core issue_tracker: https://github.com/Flagsmith/flagsmith-flutter-core/issues From ccdda64a5c24f2740664b3a007e5433ad4970c71 Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Mon, 14 Oct 2024 14:23:55 +0100 Subject: [PATCH 09/11] amend changelog --- CHANGELOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 220e170..9f573e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,6 @@ * Drop Flutter 2 support * feat: Support transient identities and traits -## 3.1.0 -* Added a null check on enabled field of flag - ## 3.0.0 * trait/value: Add support for int,float, bool and string From 661824b99dd6a59818f9677ffd6da80693be23ae Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Tue, 15 Oct 2024 20:08:10 +0100 Subject: [PATCH 10/11] idiomatic declaration --- lib/src/model/index.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/model/index.dart b/lib/src/model/index.dart index 8f56df9..c9aaef4 100644 --- a/lib/src/model/index.dart +++ b/lib/src/model/index.dart @@ -1,3 +1,5 @@ +library; + export 'feature.dart'; export 'identity.dart'; export 'flag.dart'; From c863b2e404065da9f76e0c894920db42609ac981 Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Tue, 15 Oct 2024 20:08:57 +0100 Subject: [PATCH 11/11] fix naming --- test/flagsmith_core_test.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/flagsmith_core_test.dart b/test/flagsmith_core_test.dart index c653762..3239011 100644 --- a/test/flagsmith_core_test.dart +++ b/test/flagsmith_core_test.dart @@ -53,10 +53,10 @@ void main() { Flag.seed('test_feature_b', enabled: true) ]); expect(created, isTrue); - final all0 = await storageProvider.getAll(); - expect(all0, isNotEmpty); + final all = await storageProvider.getAll(); + expect(all, isNotEmpty); expect( - all0, + all, const TypeMatcher>().having( (p0) => p0 .firstWhereOrNull((element) => element.key == 'test_feature_a'), @@ -70,10 +70,10 @@ void main() { Flag.seed('test_feature_b', enabled: true) ]); expect(created, isTrue); - final all0 = await storageProvider.getAll(); - expect(all0, isNotEmpty); + final all = await storageProvider.getAll(); + expect(all, isNotEmpty); expect( - all0, + all, const TypeMatcher>().having( (p0) => p0 .firstWhereOrNull((element) => element.key == 'test_feature_a'),