From e606892254c92d50e8072cd78c83a875d7b05942 Mon Sep 17 00:00:00 2001 From: Seungsoo Lee Date: Tue, 23 Jun 2026 18:46:04 +0900 Subject: [PATCH 1/5] [tizen_bundle] Add regression integration tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bundle() default constructor: creates empty bundle with length 0, isEmpty, isNotEmpty, keys empty - Bundle.fromMap: creates empty bundle from empty map - Bundle.fromBundle copy independence: mutating original does not affect copy; adding to copy does not affect original - Bundle.decode: round-trips List, Uint8List, and mixed types through encode/decode - operator[] (get): returns null for missing/null key, returns updated value, idempotent reads - operator[]= (set): throws ArgumentError for unsupported type, stores empty string, single-element list, empty Uint8List, full byte range 0x00–0xff - remove(): no-op for null, throws PlatformException for non-existent key, state transition after add/remove - clear(): idempotent on empty bundle, removes all mixed-type entries - length/isEmpty/isNotEmpty: reflect correct counts through add/remove operations - inherited MapMixin: containsKey, containsValue, entries, forEach, addAll, putIfAbsent --- packages/tizen_bundle/CHANGELOG.md | 1 + .../integration_test/tizen_bundle_test.dart | 391 ++++++++++++++++++ 2 files changed, 392 insertions(+) create mode 100644 packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart diff --git a/packages/tizen_bundle/CHANGELOG.md b/packages/tizen_bundle/CHANGELOG.md index 049f4a767..b17f68351 100644 --- a/packages/tizen_bundle/CHANGELOG.md +++ b/packages/tizen_bundle/CHANGELOG.md @@ -1,6 +1,7 @@ ## NEXT * Update code format. +* Add 35 integration test cases. ## 0.1.2 diff --git a/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart b/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart new file mode 100644 index 000000000..380d9b7b7 --- /dev/null +++ b/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart @@ -0,0 +1,391 @@ +// Copyright 2022 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:tizen_bundle/tizen_bundle.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + // --------------------------------------------------------------------------- + // Bundle() — default constructor + // --------------------------------------------------------------------------- + group('Bundle() default constructor', () { + testWidgets('creates an empty bundle with length 0', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + expect(bundle.length, 0); + }); + + testWidgets('isEmpty returns true for a newly created bundle', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + expect(bundle.isEmpty, true); + }); + + testWidgets('isNotEmpty returns false for a newly created bundle', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + expect(bundle.isNotEmpty, false); + }); + + testWidgets('keys returns empty iterable for an empty bundle', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + expect(bundle.keys, isEmpty); + }); + }); + + // --------------------------------------------------------------------------- + // Bundle.fromMap — factory constructor + // --------------------------------------------------------------------------- + group('Bundle.fromMap', () { + testWidgets('creates an empty bundle from an empty map', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle.fromMap({}); + expect(bundle.length, 0); + expect(bundle.isEmpty, true); + }); + }); + + // --------------------------------------------------------------------------- + // Bundle.fromBundle — copy constructor independence + // --------------------------------------------------------------------------- + group('Bundle.fromBundle copy independence', () { + testWidgets( + 'mutating the original after copy does not affect the copy', + (WidgetTester _) async { + final Bundle original = Bundle(); + original['key'] = 'originalValue'; + + final Bundle copy = Bundle.fromBundle(original); + original['key'] = 'mutatedValue'; + + // copy should still hold the value at the time of duplication + expect(copy['key'], 'originalValue'); + }, + ); + + testWidgets('copy has independent entries — adding to copy does not affect original', ( + WidgetTester _, + ) async { + final Bundle original = Bundle(); + original['key'] = 'value'; + + final Bundle copy = Bundle.fromBundle(original); + copy['newKey'] = 'newValue'; + + expect(original.containsKey('newKey'), false); + }); + }); + + // --------------------------------------------------------------------------- + // Bundle.decode — constructor from encoded string + // --------------------------------------------------------------------------- + group('Bundle.decode', () { + testWidgets('round-trips a List value through encode/decode', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['stringsKey'] = ['alpha', 'beta', 'gamma']; + final String encoded = bundle.encode(); + final Bundle decoded = Bundle.decode(encoded); + expect(decoded['stringsKey'], ['alpha', 'beta', 'gamma']); + }); + + testWidgets('round-trips a Uint8List value through encode/decode', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['bytesKey'] = Uint8List.fromList([0x00, 0x7f, 0xff]); + final String encoded = bundle.encode(); + final Bundle decoded = Bundle.decode(encoded); + expect(decoded['bytesKey'], Uint8List.fromList([0x00, 0x7f, 0xff])); + }); + + testWidgets('round-trips multiple keys of mixed types', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['s'] = 'hello'; + bundle['ss'] = ['x', 'y']; + bundle['b'] = Uint8List.fromList([1, 2, 3]); + final String encoded = bundle.encode(); + final Bundle decoded = Bundle.decode(encoded); + expect(decoded.length, 3); + expect(decoded['s'], 'hello'); + expect(decoded['ss'], ['x', 'y']); + expect(decoded['b'], Uint8List.fromList([1, 2, 3])); + }); + }); + + // --------------------------------------------------------------------------- + // operator[] — get + // --------------------------------------------------------------------------- + group('operator[] (get)', () { + testWidgets('returns null for a missing key', (WidgetTester _) async { + final Bundle bundle = Bundle(); + expect(bundle['nonExistentKey'], isNull); + }); + + testWidgets('returns null when key is null', (WidgetTester _) async { + final Bundle bundle = Bundle(); + bundle['someKey'] = 'someValue'; + // The implementation accepts Object? key and returns null for null. + expect(bundle[null], isNull); + }); + + testWidgets('returns the correct value after key is overwritten', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['key'] = 'first'; + bundle['key'] = 'second'; + expect(bundle['key'], 'second'); + }); + + testWidgets('same read-only call twice returns identical results (idempotency)', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['key'] = 'value'; + expect(bundle['key'], bundle['key']); + }); + }); + + // --------------------------------------------------------------------------- + // operator[]= — set (error path) + // --------------------------------------------------------------------------- + group('operator[]= (set)', () { + testWidgets('throws ArgumentError for an unsupported value type', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + expect( + () => bundle['key'] = 42, + throwsA(isA()), + ); + }); + + testWidgets('stores an empty string value', (WidgetTester _) async { + final Bundle bundle = Bundle(); + bundle['emptyString'] = ''; + expect(bundle['emptyString'], ''); + }); + + testWidgets('stores a single-element List', (WidgetTester _) async { + final Bundle bundle = Bundle(); + bundle['single'] = ['only']; + expect(bundle['single'], ['only']); + }); + + testWidgets('stores an empty Uint8List', (WidgetTester _) async { + final Bundle bundle = Bundle(); + bundle['emptyBytes'] = Uint8List(0); + final Uint8List result = bundle['emptyBytes']! as Uint8List; + expect(result.length, 0); + }); + + testWidgets('preserves full byte range 0x00–0xff in Uint8List', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + final Uint8List allBytes = + Uint8List.fromList(List.generate(256, (int i) => i)); + bundle['allBytes'] = allBytes; + final Uint8List result = bundle['allBytes']! as Uint8List; + expect(result, allBytes); + }); + }); + + // --------------------------------------------------------------------------- + // remove() + // --------------------------------------------------------------------------- + group('remove()', () { + testWidgets('remove(null) is a no-op and does not throw', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['key'] = 'value'; + expect(() => bundle.remove(null), returnsNormally); + expect(bundle.length, 1); + }); + + testWidgets('removing a non-existent key throws PlatformException', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + expect( + () => bundle.remove('doesNotExist'), + throwsA(isA()), + ); + }); + + testWidgets('add then remove then verify gone (state transition)', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['key'] = 'value'; + expect(bundle.containsKey('key'), true); + bundle.remove('key'); + expect(bundle.containsKey('key'), false); + expect(bundle['key'], isNull); + }); + }); + + // --------------------------------------------------------------------------- + // clear() + // --------------------------------------------------------------------------- + group('clear()', () { + testWidgets('clear() on an already-empty bundle is idempotent', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle.clear(); + expect(bundle.length, 0); + expect(bundle.isEmpty, true); + }); + + testWidgets('clear() removes all entries including mixed types', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['s'] = 'hello'; + bundle['ss'] = ['a', 'b']; + bundle['b'] = Uint8List.fromList([1]); + bundle.clear(); + expect(bundle.isEmpty, true); + expect(bundle.keys, isEmpty); + }); + }); + + // --------------------------------------------------------------------------- + // length / isEmpty / isNotEmpty — state after modifications + // --------------------------------------------------------------------------- + group('length, isEmpty, isNotEmpty', () { + testWidgets('length reflects current entry count correctly', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + expect(bundle.length, 0); + bundle['k1'] = 'v1'; + expect(bundle.length, 1); + bundle['k2'] = 'v2'; + expect(bundle.length, 2); + bundle.remove('k1'); + expect(bundle.length, 1); + }); + + testWidgets('isNotEmpty becomes true after adding an entry', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + expect(bundle.isNotEmpty, false); + bundle['key'] = 'value'; + expect(bundle.isNotEmpty, true); + }); + + testWidgets('isEmpty becomes true after removing the last entry', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['key'] = 'value'; + expect(bundle.isEmpty, false); + bundle.remove('key'); + expect(bundle.isEmpty, true); + }); + }); + + // --------------------------------------------------------------------------- + // Inherited MapMixin members + // --------------------------------------------------------------------------- + group('inherited MapMixin members', () { + testWidgets('containsKey returns true for existing key', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['key'] = 'value'; + expect(bundle.containsKey('key'), true); + }); + + testWidgets('containsKey returns false for missing key', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + expect(bundle.containsKey('missing'), false); + }); + + testWidgets('containsValue returns true for existing string value', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['key'] = 'needle'; + expect(bundle.containsValue('needle'), true); + }); + + testWidgets('containsValue returns false for absent value', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['key'] = 'value'; + expect(bundle.containsValue('absent'), false); + }); + + testWidgets('entries exposes key-value pairs correctly', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['k'] = 'v'; + final MapEntry entry = bundle.entries.single; + expect(entry.key, 'k'); + expect(entry.value, 'v'); + }); + + testWidgets('forEach iterates over all entries', (WidgetTester _) async { + final Bundle bundle = Bundle(); + bundle['a'] = '1'; + bundle['b'] = '2'; + final Map collected = {}; + bundle.forEach((String key, Object value) { + collected[key] = value; + }); + expect(collected.length, 2); + expect(collected['a'], '1'); + expect(collected['b'], '2'); + }); + + testWidgets('addAll adds all entries from a map', (WidgetTester _) async { + final Bundle bundle = Bundle(); + bundle.addAll({ + 'x': 'valueX', + 'y': 'valueY', + }); + expect(bundle.length, 2); + expect(bundle['x'], 'valueX'); + expect(bundle['y'], 'valueY'); + }); + + testWidgets('putIfAbsent inserts only when key is absent', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle(); + bundle['existing'] = 'original'; + + final Object result = bundle.putIfAbsent('existing', () => 'new'); + expect(result, 'original'); + expect(bundle['existing'], 'original'); + + final Object inserted = bundle.putIfAbsent('fresh', () => 'inserted'); + expect(inserted, 'inserted'); + expect(bundle['fresh'], 'inserted'); + }); + }); +} From 97a363da970331c1b0695b802fdc7996c55b4c85 Mon Sep 17 00:00:00 2001 From: Seungsoo Lee Date: Tue, 23 Jun 2026 19:25:06 +0900 Subject: [PATCH 2/5] [tizen_bundle] Rename bundle_test.dart to tizen_bundle_test.dart Update integration test suite to 37 test cases. --- packages/tizen_bundle/CHANGELOG.md | 2 +- .../example/integration_test/bundle_test.dart | 106 ------------------ .../integration_test/tizen_bundle_test.dart | 29 +++++ 3 files changed, 30 insertions(+), 107 deletions(-) delete mode 100644 packages/tizen_bundle/example/integration_test/bundle_test.dart diff --git a/packages/tizen_bundle/CHANGELOG.md b/packages/tizen_bundle/CHANGELOG.md index b17f68351..aafef8db9 100644 --- a/packages/tizen_bundle/CHANGELOG.md +++ b/packages/tizen_bundle/CHANGELOG.md @@ -1,7 +1,7 @@ ## NEXT * Update code format. -* Add 35 integration test cases. +* Update integration test suite to 37 test cases. ## 0.1.2 diff --git a/packages/tizen_bundle/example/integration_test/bundle_test.dart b/packages/tizen_bundle/example/integration_test/bundle_test.dart deleted file mode 100644 index 88eab1e55..000000000 --- a/packages/tizen_bundle/example/integration_test/bundle_test.dart +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2022 Samsung Electronics Co., Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/integration_test.dart'; -import 'package:tizen_bundle/tizen_bundle.dart'; - -void main() { - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - - testWidgets('can create a bundle', (WidgetTester _) async { - final Bundle bundle = Bundle(); - bundle['stringKey'] = 'stringValue'; - expect(bundle['stringKey'], 'stringValue'); - }); - - testWidgets('can create a bundle from another bundle', ( - WidgetTester _, - ) async { - final Bundle bundle = Bundle(); - bundle['stringKey'] = 'stringValue'; - - final Bundle newBundle = Bundle.fromBundle(bundle); - expect(newBundle['stringKey'], 'stringValue'); - }); - - testWidgets('can create a bundle from a map', (WidgetTester _) async { - final Bundle bundle = Bundle.fromMap({ - 'stringKey': 'stringValue', - 'stringsKey': ['value1', 'value2'], - 'bytesKey': Uint8List.fromList([0x03]), - }); - expect(bundle.length, 3); - expect(bundle['stringKey'], 'stringValue'); - expect(bundle['stringsKey'], ['value1', 'value2']); - expect(bundle['bytesKey'], Uint8List.fromList([0x03])); - }); - - testWidgets('returns all stored keys and values', (WidgetTester _) async { - final Bundle bundle = Bundle.fromMap({ - 'key1': 'value1', - 'key2': 'value2', - 'key3': 'value3', - }); - expect(bundle.keys, unorderedEquals(['key1', 'key2', 'key3'])); - expect( - bundle.values, - unorderedEquals(['value1', 'value2', 'value3']), - ); - }); - - testWidgets('checks whether the bundle is empty', (WidgetTester _) async { - final Bundle bundle = Bundle(); - bundle['stringKey'] = 'stringValue'; - expect(bundle.isNotEmpty, true); - - bundle.remove('stringKey'); - expect(bundle.isEmpty, true); - }); - - testWidgets('can add a Uint8List value', (WidgetTester _) async { - final Bundle bundle = Bundle(); - bundle['bytesKey'] = Uint8List(10); - - final Uint8List bytes = bundle['bytesKey']! as Uint8List; - expect(bytes.length, 10); - }); - - testWidgets('can add a List value', (WidgetTester _) async { - final Bundle bundle = Bundle(); - bundle['stringsKey'] = ['value1', 'value2']; - - final List strings = bundle['stringsKey']! as List; - expect(strings, ['value1', 'value2']); - }); - - testWidgets('can remove all entries', (WidgetTester _) async { - final Bundle bundle = Bundle(); - bundle['stringKey1'] = 'stringValue1'; - bundle['stringKey2'] = 'stringValue2'; - expect(bundle.length, 2); - - bundle.clear(); - expect(bundle.length, 0); - }); - - testWidgets('can remove key and its associated value', ( - WidgetTester _, - ) async { - final Bundle bundle = Bundle(); - bundle['stringKey'] = 'stringValue'; - expect(bundle.containsKey('stringKey'), true); - - bundle.remove('stringKey'); - expect(bundle.containsKey('stringKey'), false); - }); - - testWidgets('can encode and decode raw data', (WidgetTester _) async { - final Bundle bundle = Bundle(); - bundle['stringKey'] = 'stringValue'; - final String encoded = bundle.encode(); - final Bundle newBundle = Bundle.decode(encoded); - expect(newBundle['stringKey'], 'stringValue'); - }); -} diff --git a/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart b/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart index 380d9b7b7..49fe1d3d2 100644 --- a/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart +++ b/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart @@ -54,6 +54,20 @@ void main() { expect(bundle.length, 0); expect(bundle.isEmpty, true); }); + + testWidgets('creates a bundle with String, List, and Uint8List entries', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle.fromMap({ + 'stringKey': 'stringValue', + 'stringsKey': ['value1', 'value2'], + 'bytesKey': Uint8List.fromList([0x03]), + }); + expect(bundle.length, 3); + expect(bundle['stringKey'], 'stringValue'); + expect(bundle['stringsKey'], ['value1', 'value2']); + expect(bundle['bytesKey'], Uint8List.fromList([0x03])); + }); }); // --------------------------------------------------------------------------- @@ -323,6 +337,21 @@ void main() { expect(bundle.containsKey('missing'), false); }); + testWidgets('keys and values return all stored entries', ( + WidgetTester _, + ) async { + final Bundle bundle = Bundle.fromMap({ + 'key1': 'value1', + 'key2': 'value2', + 'key3': 'value3', + }); + expect(bundle.keys, unorderedEquals(['key1', 'key2', 'key3'])); + expect( + bundle.values, + unorderedEquals(['value1', 'value2', 'value3']), + ); + }); + testWidgets('containsValue returns true for existing string value', ( WidgetTester _, ) async { From fa35931b2f25494b0ff28cc90ff604eac3b44244 Mon Sep 17 00:00:00 2001 From: Seungsoo Lee Date: Tue, 30 Jun 2026 17:05:34 +0900 Subject: [PATCH 3/5] [tizen_bundle] Fix formatting in integration test --- .../example/integration_test/tizen_bundle_test.dart | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart b/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart index 49fe1d3d2..2dfc12be2 100644 --- a/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart +++ b/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart @@ -55,7 +55,8 @@ void main() { expect(bundle.isEmpty, true); }); - testWidgets('creates a bundle with String, List, and Uint8List entries', ( + testWidgets( + 'creates a bundle with String, List, and Uint8List entries', ( WidgetTester _, ) async { final Bundle bundle = Bundle.fromMap({ @@ -88,7 +89,9 @@ void main() { }, ); - testWidgets('copy has independent entries — adding to copy does not affect original', ( + testWidgets( + 'copy has independent entries — adding to copy does not affect original', + ( WidgetTester _, ) async { final Bundle original = Bundle(); @@ -166,7 +169,8 @@ void main() { expect(bundle['key'], 'second'); }); - testWidgets('same read-only call twice returns identical results (idempotency)', ( + testWidgets( + 'same read-only call twice returns identical results (idempotency)', ( WidgetTester _, ) async { final Bundle bundle = Bundle(); From 46284ccb65c5ac3a91e048fc9b84cb230df11644 Mon Sep 17 00:00:00 2001 From: Seungsoo Lee Date: Tue, 30 Jun 2026 18:06:02 +0900 Subject: [PATCH 4/5] [tizen_bundle] Fix remove() and keys getter Fix remove() to be a no-op when the key does not exist, matching the standard Map.remove() contract. Previously, removing a non-existent key threw a PlatformException (BUNDLE_ERROR_KEY_NOT_AVAILABLE). Fix the keys getter to return an independent list per call. Previously, it returned a reference to a shared static list, so calling keys on any Bundle instance would overwrite the result of a prior call on another instance. --- packages/tizen_bundle/CHANGELOG.md | 4 +++- packages/tizen_bundle/README.md | 2 +- packages/tizen_bundle/lib/tizen_bundle.dart | 13 ++++++++----- packages/tizen_bundle/pubspec.yaml | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/tizen_bundle/CHANGELOG.md b/packages/tizen_bundle/CHANGELOG.md index aafef8db9..d2419f31d 100644 --- a/packages/tizen_bundle/CHANGELOG.md +++ b/packages/tizen_bundle/CHANGELOG.md @@ -1,7 +1,9 @@ -## NEXT +## 0.1.3 * Update code format. * Update integration test suite to 37 test cases. +* Fix `remove()` to be a no-op when the key does not exist. +* Fix `keys` getter to return an independent list per call. ## 0.1.2 diff --git a/packages/tizen_bundle/README.md b/packages/tizen_bundle/README.md index c8d22e4e8..ae2245cc0 100644 --- a/packages/tizen_bundle/README.md +++ b/packages/tizen_bundle/README.md @@ -10,7 +10,7 @@ To use this package, add `tizen_bundle` as a dependency in your `pubspec.yaml` f ```yaml depenedencies: - tizen_bundle: ^0.1.2 + tizen_bundle: ^0.1.3 ``` ### Adding content to a bundle diff --git a/packages/tizen_bundle/lib/tizen_bundle.dart b/packages/tizen_bundle/lib/tizen_bundle.dart index 42814deee..68f2e2164 100644 --- a/packages/tizen_bundle/lib/tizen_bundle.dart +++ b/packages/tizen_bundle/lib/tizen_bundle.dart @@ -51,7 +51,7 @@ class Bundle extends MapMixin { (Pointer bundle) => tizen.bundle_free(bundle), ); - static final List _keys = []; + static List? _currentKeys; static void _bundleIteratorCallback( Pointer key, @@ -59,19 +59,21 @@ class Bundle extends MapMixin { Pointer keyval, Pointer userData, ) { - _keys.add(key.toDartString()); + _currentKeys!.add(key.toDartString()); } /// The keys of this. @override Iterable get keys { - _keys.clear(); + final List keys = []; + _currentKeys = keys; tizen.bundle_foreach( _handle, Pointer.fromFunction(_bundleIteratorCallback), nullptr, ); - return _keys; + _currentKeys = null; + return keys; } @override @@ -137,7 +139,8 @@ class Bundle extends MapMixin { final String keyName = key as String; return tizen.bundle_del(_handle, keyName.toNativeChar(allocator: arena)); }); - if (ret != bundle_error_e.BUNDLE_ERROR_NONE) { + if (ret != bundle_error_e.BUNDLE_ERROR_NONE && + ret != bundle_error_e.BUNDLE_ERROR_KEY_NOT_AVAILABLE) { _throwException(ret); } } diff --git a/packages/tizen_bundle/pubspec.yaml b/packages/tizen_bundle/pubspec.yaml index ee02ea533..8ab6e7b35 100644 --- a/packages/tizen_bundle/pubspec.yaml +++ b/packages/tizen_bundle/pubspec.yaml @@ -2,7 +2,7 @@ name: tizen_bundle description: Tizen data bundle APIs. homepage: https://github.com/flutter-tizen/plugins repository: https://github.com/flutter-tizen/plugins/tree/master/packages/tizen_bundle -version: 0.1.2 +version: 0.1.3 environment: sdk: ">=3.1.0 <4.0.0" From c5265488834b9a19099cb60abbba46adad377d9e Mon Sep 17 00:00:00 2001 From: Seungsoo Lee Date: Tue, 30 Jun 2026 18:06:07 +0900 Subject: [PATCH 5/5] [tizen_bundle] Update integration tests to reflect fixed behavior Update the remove() test to assert it is a no-op for a non-existent key. Add a test verifying that keys from different Bundle instances are independent (no shared static list interference). Remove the now-unused flutter/services.dart import. --- packages/tizen_bundle/CHANGELOG.md | 2 +- .../integration_test/tizen_bundle_test.dart | 22 ++++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/tizen_bundle/CHANGELOG.md b/packages/tizen_bundle/CHANGELOG.md index d2419f31d..75e243e45 100644 --- a/packages/tizen_bundle/CHANGELOG.md +++ b/packages/tizen_bundle/CHANGELOG.md @@ -1,7 +1,7 @@ ## 0.1.3 * Update code format. -* Update integration test suite to 37 test cases. +* Update integration test suite to 38 test cases. * Fix `remove()` to be a no-op when the key does not exist. * Fix `keys` getter to return an independent list per call. diff --git a/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart b/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart index 2dfc12be2..62c310600 100644 --- a/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart +++ b/packages/tizen_bundle/example/integration_test/tizen_bundle_test.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:tizen_bundle/tizen_bundle.dart'; @@ -237,14 +236,11 @@ void main() { expect(bundle.length, 1); }); - testWidgets('removing a non-existent key throws PlatformException', ( + testWidgets('removing a non-existent key is a no-op', ( WidgetTester _, ) async { final Bundle bundle = Bundle(); - expect( - () => bundle.remove('doesNotExist'), - throwsA(isA()), - ); + expect(() => bundle.remove('doesNotExist'), returnsNormally); }); testWidgets('add then remove then verify gone (state transition)', ( @@ -341,6 +337,20 @@ void main() { expect(bundle.containsKey('missing'), false); }); + testWidgets('keys of different bundles are independent', ( + WidgetTester _, + ) async { + final Bundle bundle1 = Bundle(); + bundle1['a'] = 'v1'; + final Iterable keys1 = bundle1.keys; + + final Bundle bundle2 = Bundle(); + bundle2['b'] = 'v2'; + bundle2.keys; + + expect(keys1, equals(['a'])); + }); + testWidgets('keys and values return all stored entries', ( WidgetTester _, ) async {