Closed Aidurber closed 5 years ago
@EvanHahn I've done some changes to support an array of language
and an array of fallback
. An array of language
does exactly the same thing as the fallback.
So the solution would be to either make language
an array or make fallback
an array, but that's essentially the same thing.
The implementation isn't pretty either, though there is probably a cleaner way to do it. My brain isn't working properly 😬:
// Compare a collection of languages against the specified type (language, or fallback)
function arrayHasLanguage (collection, languageCompare) {
var count = collection.length
var i = 0
var value
// Allow an override, useful for switching between options.languages and languages
var target = languageCompare || languages
for (i; i < count; i++) {
value = collection[i]
// Check if languages has the array value
if (target.hasOwnProperty(value)) {
return target[value]
}
}
}
// Get the dictionary from the supplied language(s) and fallback(s)
function getDictionary (options) {
var dictionary
var match
if (Array.isArray(options.language) && (match = arrayHasLanguage(options.language, options.languages))) {
dictionary = match
} else if (Array.isArray(options.language) && (match = arrayHasLanguage(options.language))) {
dictionary = match
} else if (Array.isArray(options.fallback) && (match = arrayHasLanguage(options.fallback, options.languages))) {
dictionary = match
} else if (Array.isArray(options.fallback) && (match = arrayHasLanguage(options.fallback))) {
dictionary = match
} else if (options.languages.hasOwnProperty(options.language)) {
dictionary = options.languages[options.language]
} else if (languages.hasOwnProperty(options.language)) {
dictionary = languages[options.language]
} else if (options.languages.hasOwnProperty(options.fallback)) {
dictionary = options.languages[options.fallback]
} else if (languages.hasOwnProperty(options.fallback)) {
dictionary = languages[options.fallback]
}
if (!dictionary) {
throw new Error('No language ' + dictionary + '.')
}
return dictionary
}
Here are the passing tests:
it('accepts fallback languages', () => {
const h = humanizer()
assert.strictEqual(h(10000, { language: 'es', fallback: 'en' }), '10 segundos')
assert.strictEqual(h(10000, { language: 'BAD', fallback: 'en' }), '10 seconds')
})
it('accepts an array of fallback languages', () => {
const h = humanizer()
assert.strictEqual(h(10000, { language: 'es', fallback: 'en' }), '10 segundos')
assert.strictEqual(h(10000, { language: 'BAD', fallback: ['es', 'en'] }), '10 segundos')
assert.strictEqual(h(10000, { language: 'BAD', fallback: ['BAD', 'BAD', 'en'] }), '10 seconds')
})
it('accepts an array of languages', () => {
const h = humanizer({
languages: {
klingon: {
y: () => 'DIS',
mo: () => 'maqtagh',
w: () => 'Hogh',
d: () => 'jaj',
h: () => 'rep',
m: () => 'tup',
s: () => 'cha\'DIch',
ms: () => 'ms'
}
}
})
assert.strictEqual(h(10000, { language: ['es', 'en'] }), '10 segundos')
assert.strictEqual(h(10000, { language: ['BAD', 'es'] }), '10 segundos')
assert.strictEqual(h(10000, { language: ['BAD', 'BAD'], fallback: 'en' }), '10 seconds')
assert.strictEqual(h(10000, { language: ['BAD', 'klingon'], fallback: 'en' }), '10 cha\'DIch')
assert.strictEqual(h(10000, { language: ['BAD'], fallback: ['klingon', 'en'] }), '10 cha\'DIch')
assert.strictEqual(h(10000, { language: ['BAD'], fallback: 'klingon' }), '10 cha\'DIch')
})
I think fallbacks
being an array would be perfect. It'd look something like this:
// ✅ These are valid (and should be tested)
humanizeDuration(100, { language: 'es' })
humanizeDuration(100, { language: 'es', fallbacks: ['en', 'fr'] })
// 🛑 These are invalid (and should be tested)
humanizeDuration(100, { language: 'es', fallbacks: 'en' })
humanizeDuration(100, { fallbacks: ['es'] })
humanizeDuration(100, { fallbacks: [] })
humanizeDuration(100, { language: ['es', 'en'] })
The tests are the hard part—would you be able to do that part?
@EvanHahn I think I get what you mean, please see the latest commit.
Hi Evan,
I've incorporated all of your changes (hopefully, I'm hungover and my brain isn't working properly). 😄
Apologies for the delay, but I am on a trip and don't have my personal computer with me. I'll plan to deploy this when I get back (the week of January 7).
@EvanHahn Please don't apologise, enjoy your holiday! There's no rush.
This has been released in humanize-duration@3.17.0
. Thanks so much! Please add yourself to the credits in the readme if you have a moment.
It's useful to provide a fallback language instead of throwing. Before, the other alternative was wrapping the humanizeDuration in a try catch and trying again with a known locale. This pull request add support for a fallback language in case of failure. If the fallback language cannot be found, then we proceed to throw as normal.
Tests added and docs updated.