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.
Note
Tests for the disallowed uses of unpaired surrogate code points are not included
because JSON does not permit unpaired surrogate code points.
If your implementation uses UTF-16 based strings (such as JavaScript String
or Java java.lang.String
)
or otherwise allows unpaired surrogates in text or literals, you will need to implement tests equivalent
to the following for syntax errors:
{
"locale": "en-US",
"src": "{\ud800}",
"expErrors": [{ "type": "syntax-error" }]
}
-
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. -
u-options.json
— Test cases for theu:
options, using built-in functions. -
functions/
— Test cases that correspond to built-in functions. The behaviour of the built-in formatters is implementation-specific so theexp
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.
Some of the tests are for functionality that is optional or for functionality that is not yet stable.
That is, the specification uses RFC2119 keywords such as SHOULD, SHOULD NOT, MAY, RECOMMENDED, or OPTIONAL,
or the specification says that given functionality is DRAFT and not yet stable.
Tests for such features have a tags
array attached to them
to mark the features that they rely on.
This may include one or more of the following:
Tag | Feature |
---|---|
u:dir |
The u:dir option |
u:id |
The u:id option |
u:locale |
The u:locale option |
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:
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 only0
and1
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:
- Let
DecimalPlaces
be 0. - Let
FailsFormat
befalse
. - Let
FailsSelect
befalse
. - Let
arg
be the resolved value of the expression operand. - If
arg
is the resolved value of an expression with a:test:function
,:test:select
, or:test:format
annotation for which resolution has succeeded, then- Let
Input
be theInput
value ofarg
. - Set
DecimalPlaces
to beDecimalPlaces
value ofarg
. - Set
FailsFormat
to beFailsFormat
value ofarg
. - Set
FailsSelect
to beFailsSelect
value ofarg
.
- Let
- Else if
arg
is a numerical value or a string matching thenumber-literal
production, then- Let
Input
be the numerical value ofarg
.
- Let
- Else,
- Emit "bad-input" Resolution Error.
- Use a fallback value as the resolved value of the expression. Further steps of this algorithm are not followed.
- If the
decimalPlaces
option is set, then- If its value resolves to a numerical integer value 0 or 1
or their corresponding string representations
'0'
or'1'
, then- Set
DecimalPlaces
to be the numerical value of the option.
- Set
- Else if its value is not an unresolved value set by option resolution,
- Emit "bad-option" Resolution Error.
- Use a fallback value as the resolved value of the expression.
- If its value resolves to a numerical integer value 0 or 1
or their corresponding string representations
- If the
fails
option is set, then- If its value resolves to the string
'always'
, then- Set
FailsFormat
to betrue
. - Set
FailsSelect
to betrue
.
- Set
- Else if its value resolves to the string
'format'
, then- Set
FailsFormat
to betrue
.
- Set
- Else if its value resolves to the string
'select'
, then- Set
FailsSelect
to betrue
.
- Set
- Else if its value does not resolve to the string
'never'
, then- Emit "bad-option" Resolution Error.
- If its value resolves to the string
When :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.
- If
FailsSelect
istrue
, calling the method will emit a Message Function Error and not return any value. - If the
Input
is 1 andDecimalPlaces
is 1, the method will return some slice of the list «'1.0'
,'1'
», depending on whether those values are included inkeys
. - If the
Input
is 1 andDecimalPlaces
is 0, the method will return the list «'1'
» ifkeys
includes'1'
, or an empty list otherwise. - If the
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:
- If
Input
is less than 0, the character-
U+002D Hyphen-Minus. - The truncated absolute integer value of
Input
, i.e. floor(abs(Input
)), formatted as a sequence of decimal digit characters (U+0030...U+0039). - If
DecimalPlaces
is 1, then- The character
.
U+002E Full Stop. - The single decimal digit character representing the value floor((abs(
Input
) - floor(abs(Input
))) * 10)
- The character
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
emit a Message Function Error.
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.
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.
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.