Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve test coverage of the I18n class #2922

Merged
merged 6 commits into from
Oct 14, 2022

Conversation

36degrees
Copy link
Contributor

Because Intl.PluralRules exists in the test environment, we didn't have any coverage for these lines of code:

// Currently our custom code can only handle positive integers, so let's
// make sure our number is one of those.
count = Math.abs(Math.floor(count))
// Look through the plural rules map to find which `pluralRule` is
// appropriate for our current `locale`.
for (var pluralRule in this.pluralRulesMap) {
if (Object.prototype.hasOwnProperty.call(this.pluralRulesMap, pluralRule)) {
var languages = this.pluralRulesMap[pluralRule]
if (languages.indexOf(locale) > -1 || languages.indexOf(localeShort) > -1) {
keySuffix = this.pluralRules[pluralRule](count)
break
}
}
}

This refactors the I18n class to split out and test the 'fallback' logic that:

  • determines which 'rules' to use to determine the plural rule (eurgh, too many things we're calling rules) based on locale
  • uses the rules to determine the plural rule…

According to Jest, we now only have 2 lines of code that are not tested:

Line 158 (we could mock out hasIntlPluralRulesSupport to return false if we think it's needed?)

return this.selectPluralRuleFromFallback(count)

Line 302 (As far as I can tell this code is unreachable):

russian: function (n) {
var lastTwo = n % 100
var last = lastTwo % 10
if (last === 1 && lastTwo !== 11) { return 'one' }
if (last >= 2 && last <= 4 && !(lastTwo >= 12 && lastTwo <= 14)) { return 'few' }
if (last === 0 || (last >= 5 && last <= 9) || (lastTwo >= 11 && lastTwo <= 14)) { return 'many' }
// Note: The 'other' suffix is only used by decimal numbers in Russian.
// We don't anticipate it being used, but it's here for consistency.
return 'other'
},

I've also moved the I18n.pluralRulesMap and I18n.pluralRules from the prototype as they feel more like 'class constants' than properties that need to exist on every object.

Suggest reviewing commit by commit as I've moved some stuff around.

@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-2922 October 14, 2022 14:45 Inactive
Copy link
Contributor

@colinrotherham colinrotherham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Work of art 🙌

This part of the execution flow is not currently tested as `Intl.PluralRules` exists in the test environment, so we never follow the 'else' part of the control flow.

Splitting it out allows us to unit test it and ensure that it works as expected.

Add error handling for unsupported locales.
This allows us to test the entire fallback logic together, passing a locale and asserting that we have the same behaviour as Intl.PluralRules, rather than testing the individual functions in i18n.PluralRules.
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-2922 October 14, 2022 16:00 Inactive
@36degrees 36degrees merged commit bfccd7e into character-count-i18n-macro Oct 14, 2022
@36degrees 36degrees deleted the i18n-unit-test-coverage branch October 14, 2022 16:08
@36degrees 36degrees restored the i18n-unit-test-coverage branch October 14, 2022 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants