// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file // for details. 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:collection/collection.dart'; import 'package:test/test.dart'; void main() { group('with an empty canonicalized map', () { late CanonicalizedMap map; setUp(() { map = CanonicalizedMap(int.parse, isValidKey: RegExp(r'^\d+$').hasMatch); }); test('canonicalizes keys on set and get', () { map['1'] = 'value'; expect(map['01'], equals('value')); }); test('get returns null for uncanonicalizable key', () { expect(map['foo'], isNull); }); test('set affects nothing for uncanonicalizable key', () { map['foo'] = 'value'; expect(map['foo'], isNull); expect(map.containsKey('foo'), isFalse); expect(map.length, equals(0)); }); test('canonicalizes keys for addAll', () { map.addAll({'1': 'value 1', '2': 'value 2', '3': 'value 3'}); expect(map['01'], equals('value 1')); expect(map['02'], equals('value 2')); expect(map['03'], equals('value 3')); }); test('uses the final value for addAll collisions', () { map.addAll({'1': 'value 1', '01': 'value 2', '001': 'value 3'}); expect(map.length, equals(1)); expect(map['0001'], equals('value 3')); }); test('clear clears the map', () { map.addAll({'1': 'value 1', '2': 'value 2', '3': 'value 3'}); expect(map, isNot(isEmpty)); map.clear(); expect(map, isEmpty); }); test('canonicalizes keys for containsKey', () { map['1'] = 'value'; expect(map.containsKey('01'), isTrue); expect(map.containsKey('2'), isFalse); }); test('containsKey returns false for uncanonicalizable key', () { expect(map.containsKey('foo'), isFalse); }); test('canonicalizes keys for putIfAbsent', () { map['1'] = 'value'; expect(map.putIfAbsent('01', () => throw Exception("shouldn't run")), equals('value')); expect(map.putIfAbsent('2', () => 'new value'), equals('new value')); }); test('canonicalizes keys for remove', () { map['1'] = 'value'; expect(map.remove('2'), isNull); expect(map.remove('01'), equals('value')); expect(map, isEmpty); }); test('remove returns null for uncanonicalizable key', () { expect(map.remove('foo'), isNull); }); test('containsValue returns whether a value is in the map', () { map['1'] = 'value'; expect(map.containsValue('value'), isTrue); expect(map.containsValue('not value'), isFalse); }); test('isEmpty returns whether the map is empty', () { expect(map.isEmpty, isTrue); map['1'] = 'value'; expect(map.isEmpty, isFalse); map.remove('01'); expect(map.isEmpty, isTrue); }); test("isNotEmpty returns whether the map isn't empty", () { expect(map.isNotEmpty, isFalse); map['1'] = 'value'; expect(map.isNotEmpty, isTrue); map.remove('01'); expect(map.isNotEmpty, isFalse); }); test('length returns the number of pairs in the map', () { expect(map.length, equals(0)); map['1'] = 'value 1'; expect(map.length, equals(1)); map['01'] = 'value 01'; expect(map.length, equals(1)); map['02'] = 'value 02'; expect(map.length, equals(2)); }); test('uses original keys for keys', () { map['001'] = 'value 1'; map['02'] = 'value 2'; expect(map.keys, equals(['001', '02'])); }); test('uses original keys for forEach', () { map['001'] = 'value 1'; map['02'] = 'value 2'; var keys = []; map.forEach((key, value) => keys.add(key)); expect(keys, equals(['001', '02'])); }); test('values returns all values in the map', () { map.addAll( {'1': 'value 1', '01': 'value 01', '2': 'value 2', '03': 'value 03'}); expect(map.values, equals(['value 01', 'value 2', 'value 03'])); }); test('entries returns all key-value pairs in the map', () { map.addAll({ '1': 'value 1', '01': 'value 01', '2': 'value 2', }); var entries = map.entries.toList(); expect(entries[0].key, '01'); expect(entries[0].value, 'value 01'); expect(entries[1].key, '2'); expect(entries[1].value, 'value 2'); }); test('addEntries adds key-value pairs to the map', () { map.addEntries([ const MapEntry('1', 'value 1'), const MapEntry('01', 'value 01'), const MapEntry('2', 'value 2'), ]); expect(map, {'01': 'value 01', '2': 'value 2'}); }); test('cast returns a new map instance', () { expect(map.cast(), isNot(same(map))); }); }); group('CanonicalizedMap builds an informative string representation', () { dynamic map; setUp(() { map = CanonicalizedMap(int.parse, isValidKey: RegExp(r'^\d+$').hasMatch); }); test('for an empty map', () { expect(map.toString(), equals('{}')); }); test('for a map with one value', () { map.addAll({'1': 'value 1'}); expect(map.toString(), equals('{1: value 1}')); }); test('for a map with multiple values', () { map.addAll( {'1': 'value 1', '01': 'value 01', '2': 'value 2', '03': 'value 03'}); expect( map.toString(), equals('{01: value 01, 2: value 2, 03: value 03}')); }); test('for a map with a loop', () { map.addAll({'1': 'value 1', '2': map}); expect(map.toString(), equals('{1: value 1, 2: {...}}')); }); }); group('CanonicalizedMap.from', () { test('canonicalizes its keys', () { var map = CanonicalizedMap.from( {'1': 'value 1', '2': 'value 2', '3': 'value 3'}, int.parse); expect(map['01'], equals('value 1')); expect(map['02'], equals('value 2')); expect(map['03'], equals('value 3')); }); test('uses the final value for collisions', () { var map = CanonicalizedMap.from( {'1': 'value 1', '01': 'value 2', '001': 'value 3'}, int.parse); expect(map.length, equals(1)); expect(map['0001'], equals('value 3')); }); }); group('CanonicalizedMap.fromEntries', () { test('canonicalizes its keys', () { var map = CanonicalizedMap.fromEntries( {'1': 'value 1', '2': 'value 2', '3': 'value 3'}.entries, int.parse); expect(map['01'], equals('value 1')); expect(map['02'], equals('value 2')); expect(map['03'], equals('value 3')); }); test('uses the final value for collisions', () { var map = CanonicalizedMap.fromEntries( {'1': 'value 1', '01': 'value 2', '001': 'value 3'}.entries, int.parse); expect(map.length, equals(1)); expect(map['0001'], equals('value 3')); }); }); group('CanonicalizedMap.toMapOfCanonicalKeys', () { test('convert to a `Map`', () { var map = CanonicalizedMap.from( {'1': 'value 1', '2': 'value 2', '3': 'value 3'}, int.parse); var map2 = map.toMapOfCanonicalKeys(); expect(map2, isNot(isA())); expect(map2[1], equals('value 1')); expect(map2[2], equals('value 2')); expect(map2[3], equals('value 3')); expect(map2, equals({1: 'value 1', 2: 'value 2', 3: 'value 3'})); }); }); group('CanonicalizedMap.toMap', () { test('convert to a `Map`', () { var map = CanonicalizedMap.from( {'1': 'value 1', '2': 'value 2', '3': 'value 3'}, int.parse); var map2 = map.toMap(); expect(map2, isNot(isA())); expect(map2['1'], equals('value 1')); expect(map2['2'], equals('value 2')); expect(map2['3'], equals('value 3')); expect(map2, equals({'1': 'value 1', '2': 'value 2', '3': 'value 3'})); }); }); group('CanonicalizedMap.copy', () { test('copy instance', () { var map = CanonicalizedMap.from( {'1': 'value 1', '2': 'value 2', '3': 'value 3'}, int.parse); var map2 = map.copy(); expect(map2['01'], equals('value 1')); expect(map2['02'], equals('value 2')); expect(map2['03'], equals('value 3')); expect(map2['1'], equals('value 1')); expect(map2['2'], equals('value 2')); expect(map2['3'], equals('value 3')); expect(map2, equals({'1': 'value 1', '2': 'value 2', '3': 'value 3'})); var map3 = Map.fromEntries(map2.entries); expect(map3, equals({'1': 'value 1', '2': 'value 2', '3': 'value 3'})); }); }); }