-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add list format * Add test * Add readme and changelog * Dart fix * Add vm test * Add license header to file * Changes as per review * Use web coverage
- Loading branch information
Showing
15 changed files
with
329 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,5 @@ on: | |
jobs: | ||
health: | ||
uses: dart-lang/ecosystem/.github/workflows/health.yaml@main | ||
with: | ||
coverage_web: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
## 0.2.0 | ||
|
||
- Add list format. | ||
|
||
## 0.1.0 | ||
|
||
- Initial version. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// Copyright (c) 2023, 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. | ||
|
||
export 'src/list_format/list_format.dart'; | ||
export 'src/list_format/list_format_options.dart'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright (c) 2023, 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 '../options.dart'; | ||
import '../test_checker.dart'; | ||
import 'list_format_impl.dart'; | ||
import 'list_format_options.dart'; | ||
|
||
class ListFormat { | ||
final ListFormatOptions _options; | ||
final ListFormatImpl _listFormatImpl; | ||
|
||
const ListFormat(this._options, this._listFormatImpl); | ||
|
||
/// Locale-dependant concatenation of lists, for example in `en-US` locale: | ||
/// ```dart | ||
/// format(['A', 'B', 'C']) == 'A, B, and C' | ||
/// ``` | ||
String format( | ||
List<String> list, { | ||
LocaleMatcher localeMatcher = LocaleMatcher.bestfit, | ||
Type type = Type.conjunction, | ||
ListStyle style = ListStyle.long, | ||
}) { | ||
if (isInTest) { | ||
return '${list.join(', ')}//${_listFormatImpl.locale}'; | ||
} else { | ||
return _listFormatImpl.formatImpl(list, _options); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright (c) 2023, 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 '../locale.dart'; | ||
import 'list_format_impl.dart'; | ||
import 'list_format_options.dart'; | ||
|
||
ListFormatImpl getListFormatter4X(Locale locale) => ListFormat4X(locale); | ||
|
||
class ListFormat4X extends ListFormatImpl { | ||
ListFormat4X(super.locale); | ||
|
||
@override | ||
String formatImpl(List<String> list, ListFormatOptions options) { | ||
throw UnimplementedError('Insert diplomat bindings here'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright (c) 2023, 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:js/js.dart'; | ||
import 'package:js/js_util.dart'; | ||
|
||
import '../locale.dart'; | ||
import '../options.dart'; | ||
import '../utils.dart'; | ||
import 'list_format_impl.dart'; | ||
import 'list_format_options.dart'; | ||
|
||
ListFormatImpl? getListFormatterECMA( | ||
Locale locale, | ||
LocaleMatcher localeMatcher, | ||
) => | ||
_ListFormatECMA.tryToBuild(locale, localeMatcher); | ||
|
||
@JS('Intl.ListFormat') | ||
class ListFormatJS { | ||
external factory ListFormatJS([List<String> locale, Object options]); | ||
external String format(List<String> list); | ||
} | ||
|
||
@JS('Intl.ListFormat.supportedLocalesOf') | ||
external List<String> supportedLocalesOfJS( | ||
List<String> listOfLocales, [ | ||
Object options, | ||
]); | ||
|
||
class _ListFormatECMA extends ListFormatImpl { | ||
_ListFormatECMA(super.locales); | ||
|
||
static ListFormatImpl? tryToBuild( | ||
Locale locale, | ||
LocaleMatcher localeMatcher, | ||
) { | ||
final supportedLocales = supportedLocalesOf(locale, localeMatcher); | ||
return supportedLocales.isNotEmpty | ||
? _ListFormatECMA(supportedLocales.first) | ||
: null; | ||
} | ||
|
||
static List<String> supportedLocalesOf( | ||
String locale, | ||
LocaleMatcher localeMatcher, | ||
) { | ||
final o = newObject<Object>(); | ||
setProperty(o, 'localeMatcher', localeMatcher.jsName); | ||
return List.from(supportedLocalesOfJS([localeToJsFormat(locale)], o)); | ||
} | ||
|
||
@override | ||
String formatImpl(List<String> list, ListFormatOptions options) { | ||
return ListFormatJS([localeToJsFormat(locale)], options.toJsOptions()) | ||
.format(list); | ||
} | ||
} | ||
|
||
extension on ListFormatOptions { | ||
Object toJsOptions() { | ||
final o = newObject<Object>(); | ||
setProperty(o, 'localeMatcher', localeMatcher.jsName); | ||
setProperty(o, 'type', type.name); | ||
setProperty(o, 'style', style.name); | ||
return o; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright (c) 2023, 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 '../../ecma_policy.dart'; | ||
import '../ecma/ecma_policy.dart'; | ||
import '../locale.dart'; | ||
import '../options.dart'; | ||
import '../utils.dart'; | ||
import 'list_format_4x.dart'; | ||
import 'list_format_options.dart'; | ||
import 'list_format_stub.dart' if (dart.library.js) 'list_format_ecma.dart'; | ||
|
||
abstract class ListFormatImpl { | ||
final Locale locale; | ||
|
||
ListFormatImpl(this.locale); | ||
|
||
String formatImpl(List<String> list, ListFormatOptions options); | ||
|
||
factory ListFormatImpl.build( | ||
Locale locales, | ||
LocaleMatcher localeMatcher, | ||
EcmaPolicy ecmaPolicy, | ||
) => | ||
buildFormatter( | ||
locales, | ||
localeMatcher, | ||
ecmaPolicy, | ||
getListFormatterECMA, | ||
getListFormatter4X, | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright (c) 2023, 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 '../options.dart'; | ||
|
||
class ListFormatOptions { | ||
final Type type; | ||
final ListStyle style; | ||
final LocaleMatcher localeMatcher; | ||
|
||
const ListFormatOptions({ | ||
this.type = Type.conjunction, | ||
this.style = ListStyle.long, | ||
this.localeMatcher = LocaleMatcher.bestfit, | ||
}); | ||
} | ||
|
||
/// Indicates the type of grouping. | ||
enum Type { | ||
/// For "and"-based grouping of the list items: "A, B, and C". | ||
conjunction, | ||
|
||
/// For "or"-based grouping of the list items: "A, B, or C". | ||
disjunction, | ||
|
||
/// Grouping the list items as a unit: "A, B, C". | ||
unit; | ||
} | ||
|
||
/// Indicates the grouping style (for example, whether list separators and | ||
/// conjunctions are included). | ||
enum ListStyle { | ||
/// Example: "A, B, and C". | ||
long, | ||
|
||
/// Example: "A, B, C". | ||
short, | ||
|
||
/// Example: "A B C". | ||
narrow; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) 2023, 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 '../locale.dart'; | ||
import '../options.dart'; | ||
import 'list_format_impl.dart'; | ||
|
||
ListFormatImpl? getListFormatterECMA( | ||
Locale locale, | ||
LocaleMatcher localeMatcher, | ||
) => | ||
throw UnimplementedError('Cannot use ECMA outside of web environments.'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Copyright (c) 2023, 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. | ||
|
||
@TestOn('browser') | ||
library; | ||
|
||
import 'package:intl4x/ecma_policy.dart'; | ||
import 'package:intl4x/intl4x.dart'; | ||
import 'package:intl4x/src/list_format/list_format_options.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
import '../utils.dart'; | ||
|
||
void main() { | ||
group('List style options', () { | ||
final list = ['A', 'B', 'C']; | ||
final intl = Intl(defaultLocale: 'en_US'); | ||
testWithFormatting('long', () { | ||
final listFormat = | ||
intl.listFormat(const ListFormatOptions(style: ListStyle.long)); | ||
expect(listFormat.format(list), 'A, B, and C'); | ||
}); | ||
testWithFormatting('short', () { | ||
final listFormat = | ||
intl.listFormat(const ListFormatOptions(style: ListStyle.short)); | ||
expect(listFormat.format(list), 'A, B, & C'); | ||
}); | ||
testWithFormatting('narrow', () { | ||
final listFormat = | ||
intl.listFormat(const ListFormatOptions(style: ListStyle.narrow)); | ||
expect(listFormat.format(list), 'A, B, C'); | ||
}); | ||
}); | ||
|
||
group('List type options', () { | ||
final list = ['A', 'B', 'C']; | ||
final intl = Intl(defaultLocale: 'en_US'); | ||
testWithFormatting('long', () { | ||
final listFormat = | ||
intl.listFormat(const ListFormatOptions(type: Type.conjunction)); | ||
expect(listFormat.format(list), 'A, B, and C'); | ||
}); | ||
testWithFormatting('short', () { | ||
final listFormat = | ||
intl.listFormat(const ListFormatOptions(type: Type.disjunction)); | ||
expect(listFormat.format(list), 'A, B, or C'); | ||
}); | ||
testWithFormatting('narrow', () { | ||
final listFormat = | ||
intl.listFormat(const ListFormatOptions(type: Type.unit)); | ||
expect(listFormat.format(list), 'A, B, C'); | ||
}); | ||
}); | ||
|
||
group('List style and type combinations', () { | ||
final list = ['A', 'B', 'C']; | ||
final intl = Intl(ecmaPolicy: const AlwaysEcma(), defaultLocale: 'en_US'); | ||
testWithFormatting('long', () { | ||
final formatter = intl.listFormat(const ListFormatOptions( | ||
style: ListStyle.narrow, type: Type.conjunction)); | ||
expect(formatter.format(list), 'A, B, C'); | ||
}); | ||
testWithFormatting('short', () { | ||
final formatter = intl.listFormat( | ||
const ListFormatOptions(style: ListStyle.short, type: Type.unit)); | ||
expect(formatter.format(list), 'A, B, C'); | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright (c) 2023, 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. | ||
|
||
@TestOn('vm') | ||
library; | ||
|
||
import 'package:intl4x/intl4x.dart'; | ||
import 'package:intl4x/list_format.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
import '../utils.dart'; | ||
|
||
void main() { | ||
final list = ['A', 'B', 'C']; | ||
test('Does not compare in tests', () { | ||
final locale = 'de_DE'; | ||
final listFormatGerman = Intl(defaultLocale: locale) | ||
.listFormat(const ListFormatOptions(style: ListStyle.long)); | ||
expect(listFormatGerman.format(list), '${list.join(', ')}//$locale'); | ||
}); | ||
|
||
testWithFormatting('long', () { | ||
final intl = Intl(defaultLocale: 'en_US'); | ||
final listFormat = | ||
intl.listFormat(const ListFormatOptions(style: ListStyle.long)); | ||
expect(() => listFormat.format(list), throwsA(isA<UnimplementedError>())); | ||
}); | ||
} |