Skip to content

Commit

Permalink
Fix flow types and enable flow testing on CI
Browse files Browse the repository at this point in the history
Types fixed by making "getChoiceIndex" method follow types and be
a class property rather than class method. Class methods are "read-only"
in flow and that wasn't compatible with flow types that are defining
that function as a property (to allow overriding through prototype changing).
  • Loading branch information
rchl committed May 27, 2020
1 parent 60fbd6e commit 6fd1121
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 31 deletions.
5 changes: 4 additions & 1 deletion .circleci/config.yml
Expand Up @@ -41,7 +41,10 @@ jobs:
- run:
name: Lint
command: yarn lint
#- run: yarn flow
- run:
name: Flow Types
# https://discuss.circleci.com/t/circleci-terminal-is-a-tty-but-term-is-not-set/9965/8
command: TERM=dumb yarn flow
- run:
name: TS Types
command: yarn test:types
Expand Down
3 changes: 2 additions & 1 deletion decls/i18n.js
Expand Up @@ -52,6 +52,7 @@ declare type DateTimeFormatResult = string;
declare type NumberFormatResult = string;
declare type MissingHandler = (locale: Locale, key: Path, vm?: any) => string | void;
declare type PostTranslationHandler = (str: string, key?: string) => string;
declare type GetChoiceIndex = (choice: number, choicesLength: number) => number
declare type ComponentInstanceCreatedListener = (newI18n: I18n, rootI18n: I18n) => void;

declare type FormattedNumberPartType = 'currency' | 'decimal' | 'fraction' | 'group' | 'infinity' | 'integer' | 'literal' | 'minusSign' | 'nan' | 'plusSign' | 'percentSign';
Expand Down Expand Up @@ -144,7 +145,7 @@ declare interface I18n {
setNumberFormat (locale: Locale, format: NumberFormat): void,
mergeNumberFormat (locale: Locale, format: NumberFormat): void,
n (value: number, ...args: any): NumberFormatResult,
getChoiceIndex: (choice: number, choicesLength: number) => number,
getChoiceIndex: GetChoiceIndex,
pluralizationRules: PluralizationRules,
preserveDirectiveContent: boolean
};
Expand Down
65 changes: 36 additions & 29 deletions src/index.js
Expand Up @@ -62,6 +62,7 @@ export default class VueI18n {
pluralizationRules: {
[lang: string]: (choice: number, choicesLength: number) => number
}
getChoiceIndex: GetChoiceIndex

constructor (options: I18nOptions = {}) {
// Auto install if it is not done yet and `window` has `Vue`.
Expand Down Expand Up @@ -110,6 +111,41 @@ export default class VueI18n {
this._warnHtmlInMessage = options.warnHtmlInMessage || 'off'
this._postTranslation = options.postTranslation || null

/**
* @param choice {number} a choice index given by the input to $tc: `$tc('path.to.rule', choiceIndex)`
* @param choicesLength {number} an overall amount of available choices
* @returns a final choice index
*/
this.getChoiceIndex = (choice: number, choicesLength: number): number => {
const thisPrototype = Object.getPrototypeOf(this)
if (thisPrototype && thisPrototype.getChoiceIndex) {
const prototypeGetChoiceIndex = (thisPrototype.getChoiceIndex: any)
return (prototypeGetChoiceIndex: GetChoiceIndex).call(this, choice, choicesLength)
}

// Default (old) getChoiceIndex implementation - english-compatible
const defaultImpl = (_choice: number, _choicesLength: number) => {
_choice = Math.abs(_choice)

if (_choicesLength === 2) {
return _choice
? _choice > 1
? 1
: 0
: 1
}

return _choice ? Math.min(_choice, 2) : 0
}

if (this.locale in this.pluralizationRules) {
return this.pluralizationRules[this.locale].apply(this, [choice, choicesLength])
} else {
return defaultImpl(choice, choicesLength)
}
}


this._exist = (message: Object, key: Path): boolean => {
if (!message || !key) { return false }
if (!isNull(this._path.getPathValue(message, key))) { return true }
Expand Down Expand Up @@ -231,7 +267,6 @@ export default class VueI18n {

onComponentInstanceCreated (newI18n: I18n) {
if (this._componentInstanceCreatedListener) {
// $FlowFixMe
this._componentInstanceCreatedListener(newI18n, this)
}
}
Expand Down Expand Up @@ -680,34 +715,6 @@ export default class VueI18n {
return choices[choice].trim()
}
/**
* @param choice {number} a choice index given by the input to $tc: `$tc('path.to.rule', choiceIndex)`
* @param choicesLength {number} an overall amount of available choices
* @returns a final choice index
*/
getChoiceIndex (choice: number, choicesLength: number): number {
// Default (old) getChoiceIndex implementation - english-compatible
const defaultImpl = (_choice: number, _choicesLength: number) => {
_choice = Math.abs(_choice)
if (_choicesLength === 2) {
return _choice
? _choice > 1
? 1
: 0
: 1
}
return _choice ? Math.min(_choice, 2) : 0
}
if (this.locale in this.pluralizationRules) {
return this.pluralizationRules[this.locale].apply(this, [choice, choicesLength])
} else {
return defaultImpl(choice, choicesLength)
}
}
tc (key: Path, choice?: number, ...values: any): TranslateResult {
return this._tc(key, this.locale, this._getMessages(), null, choice, ...values)
}
Expand Down

0 comments on commit 6fd1121

Please sign in to comment.