Skip to content

Latest commit

 

History

History

test

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

Unicode MessageFormat Test Suite

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 the u: 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 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.

Error Codes

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.

Test Tags

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

Test Functions

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.

Operands

The function :test:function requires a Number Operand as its operand.

Options

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.

Behavior

When resolving a :test:function expression, its Input, DecimalPlaces, FailsFormat, and FailsSelect values are determined as follows:

  1. Let DecimalPlaces be 0.
  2. Let FailsFormat be false.
  3. Let FailsSelect be false.
  4. Let arg be the resolved value of the expression operand.
  5. 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
    1. Let Input be the Input value of arg.
    2. Set DecimalPlaces to be DecimalPlaces value of arg.
    3. Set FailsFormat to be FailsFormat value of arg.
    4. Set FailsSelect to be FailsSelect value of arg.
  6. Else if arg is a numerical value or a string matching the number-literal production, then
    1. Let Input be the numerical value of arg.
  7. Else,
    1. Emit "bad-input" Resolution Error.
    2. Use a fallback value as the resolved value of the expression. Further steps of this algorithm are not followed.
  8. If the decimalPlaces option is set, then
    1. If its value resolves to a numerical integer value 0 or 1 or their corresponding string representations '0' or '1', then
      1. Set DecimalPlaces to be the numerical value of the option.
    2. Else if its value is not an unresolved value set by option resolution,
      1. Emit "bad-option" Resolution Error.
      2. Use a fallback value as the resolved value of the expression.
  9. If the fails option is set, then
    1. If its value resolves to the string 'always', then
      1. Set FailsFormat to be true.
      2. Set FailsSelect to be true.
    2. Else if its value resolves to the string 'format', then
      1. Set FailsFormat to be true.
    3. Else if its value resolves to the string 'select', then
      1. Set FailsSelect to be true.
    4. Else if its value does not resolve to the string 'never', then
      1. Emit "bad-option" Resolution Error.

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 is true, calling the method will emit a Message Function Error and not return any value.
  • If the 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.
  • If the Input is 1 and DecimalPlaces is 0, the method will return the list « '1' » if keys 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:

  1. If Input is less than 0, the character - U+002D Hyphen-Minus.
  2. The truncated absolute integer value of Input, i.e. floor(abs(Input)), formatted as a sequence of decimal digit characters (U+0030...U+0039).
  3. If DecimalPlaces is 1, then
    1. The character . U+002E Full Stop.
    2. The single decimal digit character representing the value floor((abs(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 emit a Message Function Error.

: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.

About

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.