Files
zeekay 80e746ad96 @hanzo/i18n 0.5.4: Say and english, a plain module's t
A module that words a sentence outside React takes `t: Say = english`
last. The type and its English default were copied into @hanzo/app and
are about to be needed in @hanzo/iam, @hanzo/plans and @hanzo/usage as
the app's lib moves to the packages that own it; one copy lives here.
2026-10-22 19:46:07 -07:00

55 lines
2.0 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from 'node:assert/strict'
import test from 'node:test'
import { createElement, type ReactNode } from 'react'
import { renderToStaticMarkup } from 'react-dom/server'
import { english, isolate, phrase, pieces, translate, type Say } from '../src/index.ts'
import { useI18n } from '../src/react.ts'
test('pieces cut a translation at its arguments, in the translation’s order', () => {
assert.deepEqual(pieces({ 'By {who} on {day}': 'Am {day} von {who}' }, 'By {who} on {day}'), [
'Am ',
{ name: 'day' },
' von ',
{ name: 'who' },
])
assert.deepEqual(pieces({}, '{n}'), [{ name: 'n' }])
assert.deepEqual(pieces({}, 'plain'), ['plain'])
})
test('translate is pieces joined, an argument with no value left visible', () => {
assert.equal(translate({}, '{n} of {total}', { n: 3 }), '3 of {total}')
})
test('english is a Say: the English with its arguments filled, nothing looked up', () => {
const t: Say = english
assert.equal(t('Hello, {name}.', { name: 'Ada' }), 'Hello, Ada.')
assert.equal(t('{count} left', { count: 3 }), '3 left')
assert.equal(t('No {gap} here'), 'No {gap} here')
})
test('isolate wraps text in a first-strong isolate, invisible in any direction', () => {
assert.equal(isolate('1,150–1,400'), '⁨1,150–1,400⁩')
})
test('phrase is its argument', () => {
assert.equal(phrase('About Us'), 'About Us')
})
/** What `t` returns, rendered, outside any provider: English, left to right. */
function said(source: string, values?: Record<string, ReactNode>): string {
function Probe() {
const { t } = useI18n()
return createElement('p', null, values ? t(source, values) : t(source))
}
return renderToStaticMarkup(createElement(Probe))
}
test('t with text arguments is a string; with an element it is one sentence holding it', () => {
assert.equal(said('{n} tasks', { n: 39 }), '<p>39 tasks</p>')
assert.equal(
said('By continuing, you agree to the {terms}.', { terms: createElement('a', { href: '/terms' }, 'Terms') }),
'<p>By continuing, you agree to the <a href="/terms">Terms</a>.</p>',
)
})