For information about MessageFormat 2.0, see Unicode Locale Data Markup Language (LDML): Part 9: Message Format
The tests in the ./tests/
directory were originally copied from the messageformat project and are here relicensed by their original author (Eemeli Aro) under the Unicode License.
These test files are intended to be useful for testing multiple different message processors in different ways:
syntax.json
— Test cases that do not depend on any registry definitions.
syntax-errors.json
— Strings that should produce a Syntax Error when parsed.
data-model-errors.json
- Strings that should produce a Data Model Error when processed. Error names are defined in “MessageFormat 2.0 Errors” in the spec.
functions/
— Test cases that correspond to built-in functions. The behaviour of the built-in formatters is implementation-specific so the exp
field is often omitted and assertions are made on error cases.
Some examples of test harnesses using these tests, from the source repository:
A JSON schema is included for the test files in this repository.
The following table relates the error names used in the JSON schema to the error names used in “MessageFormat 2.0 Errors” in the spec.
Spec | Schema |
---|---|
Bad Operand | bad-operand |
Bad Option | bad-option |
Bad Selector | bad-selector |
Bad Variant Key | bad-variant-key |
Duplicate Declaration | duplicate-declaration |
Duplicate Option Name | duplicate-option-name |
Duplicate Variant | duplicate-variant |
Missing Fallback Variant | missing-fallback-variant |
Missing Selector Annotation | missing-selector-annotation |
Syntax Error | syntax-error |
Unknown Function | unknown-function |
Unresolved Variable | unresolved-variable |
Variant Key Mismatch | variant-key-mismatch |
The “Message Function Error” error name used in the spec is not included in the schema, as it is intended to be an umbrella category for implementation-specific errors.
As the behaviour of some of the default registry functions such as :number
and :datetime
is dependent on locale-specific data and may vary between implementations, the following functions are defined for test use only:
:test:function
This function is valid both as a selector and as a formatter.
The function :test:function
requires a Number Operand as its operand.
The following options are available on :test:function
:
decimalPlaces
, a digit size option for which only 0
and 1
are valid values.0
1
fails
never
(default)select
format
always
All other options and their values are ignored.
When resolving a :test:function
expression, its Input
, DecimalPlaces
, FailsFormat
, and FailsSelect
values are determined as follows:
DecimalPlaces
be 0.FailsFormat
be false
.FailsSelect
be false
.arg
be the resolved value of the expression operand.arg
is the resolved value of an expression with a :test:function
, :test:select
, or :test:format
annotation for which resolution has succeeded, thenInput
be the Input
value of arg
.DecimalPlaces
to be DecimalPlaces
value of arg
.FailsFormat
to be FailsFormat
value of arg
.FailsSelect
to be FailsSelect
value of arg
.arg
is a numerical value or a string matching the number-literal
production, thenInput
be the numerical value of arg
.decimalPlaces
option is set, then'0'
or '1'
, thenDecimalPlaces
to be the numerical value of the option.fails
option is set, then'always'
, thenFailsFormat
to be true
.FailsSelect
to be true
.'format'
, thenFailsFormat
to be true
.'select'
, thenFailsSelect
to be true
.'never'
, thenWhen :test:function
is used as a selector, the behaviour of calling it as the rv
value of MatchSelectorKeys(rv
, keys
) (see Resolve Preferences for more information) depends on its Input
, DecimalPlaces
and FailsSelect
values.
FailsSelect
is true
, calling the method will fail and not return any value.Input
is 1 and DecimalPlaces
is 1, the method will return some slice of the list « '1.0'
, '1'
», depending on whether those values are included in keys
.Input
is 1 and DecimalPlaces
is 0, the method will return the list « '1'
» if keys
includes '1'
, or an empty list otherwise.Input
is any other value, the method will return an empty list.When an expression with a :test:function
annotation is assigned to a variable by a declaration and that variable is used as an option value, its resolved value is the Input
value.
When :test:function
is used as a formatter, a placeholder resolving to a value with a :test:function
expression is formatted as a concatenation of the following parts:
Input
is less than 0, the character -
U+002D Hyphen-Minus.Input
, i.e. floor(abs(Input
)), formatted as a sequence of decimal digit characters (U+0030...U+0039).DecimalPlaces
is 1, then.
U+002E Full Stop.Input
) - floor(abs(Input
))) * 10)If the formatting target is a sequence of parts, each of the above parts will be emitted separately rather than being concatenated into a single string.
If FailsFormat
is true
, attempting to format the placeholder to any formatting target will fail.
:test:select
This function accepts the same operands and options, and behaves exactly the same as :test:function
, except that it cannot be used for formatting.
When :test:select
is used as a formatter, a “not-formattable” error is emitted and the placeholder is formatted with a fallback value.
:test:format
This function accepts the same operands and options, and behaves exactly the same as :test:function
, except that it cannot be used for selection.
When :test:format
is used as a selector, the steps under 2.iii. of Resolve Selectors are followed.