fix: add missing language getters

This commit is contained in:
Lei Nelissen
2026-01-29 14:19:24 +01:00
parent 8c8f52d3ef
commit 2c0e955816
8 changed files with 2067 additions and 529 deletions
+17
View File
@@ -0,0 +1,17 @@
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: Install Node dependencies
run: pnpm install
- name: Run tests
run: pnpm test
+7
View File
@@ -0,0 +1,7 @@
module.exports = {
preset: 'react-native',
transformIgnorePatterns: [
'node_modules/(?!(react-native|@react-native|react-native-.*|@react-navigation|i18n-js|make-plural)/)',
],
setupFiles: ['<rootDir>/jest.setup.js'],
};
+25
View File
@@ -0,0 +1,25 @@
// Mock react-native-localize
jest.mock('react-native-localize', () => ({
findBestLanguageTag: jest.fn(() => ({
languageTag: 'en',
isRTL: false,
})),
getLocales: jest.fn(() => [
{ countryCode: 'US', languageTag: 'en-US', languageCode: 'en', isRTL: false },
]),
getNumberFormatSettings: jest.fn(() => ({
decimalSeparator: '.',
groupingSeparator: ',',
})),
getCalendar: jest.fn(() => 'gregorian'),
getCountry: jest.fn(() => 'US'),
getCurrencies: jest.fn(() => ['USD']),
getTemperatureUnit: jest.fn(() => 'celsius'),
getTimeZone: jest.fn(() => 'UTC'),
uses24HourClock: jest.fn(() => true),
usesMetricSystem: jest.fn(() => true),
usesAutoDateAndTime: jest.fn(() => true),
usesAutoTimeZone: jest.fn(() => true),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
}));
+7 -20
View File
@@ -7,13 +7,13 @@
"android": "react-native run-android",
"ios": "react-native run-ios --scheme \"Fintunes\"",
"start": "react-native start",
"test": "jest",
"lint": "eslint ./src --ext .js,.jsx,.ts,.tsx && tsc --noEmit",
"build:ios": "react-native bundle --entry-file='index.js' --bundle-output='./ios/main.jsbundle' --dev=false --platform='ios'"
},
"dependencies": {
"@d11/react-native-fast-image": "8.13.0",
"@react-native-async-storage/async-storage": "^2.2.0",
"@sbaiahmed1/react-native-blur": "^4.4.2",
"@react-native-community/datetimepicker": "^8.6.0",
"@react-native-community/netinfo": "^11.4.1",
"@react-navigation/bottom-tabs": "7.10.1",
@@ -22,6 +22,7 @@
"@react-navigation/native-stack": "7.10.1",
"@react-navigation/stack": "^7.6.16",
"@reduxjs/toolkit": "2.11.2",
"@sbaiahmed1/react-native-blur": "^4.5.3",
"@shopify/flash-list": "2.2.0",
"@shopify/react-native-skia": "2.4.14",
"date-fns": "4.1.0",
@@ -55,8 +56,9 @@
},
"devDependencies": {
"@babel/core": "7.28.6",
"@babel/preset-env": "^7.28.6",
"@babel/runtime": "7.28.6",
"@react-native-community/cli": "^20.0.0",
"@react-native-community/cli": "^20.1.1",
"@react-native/babel-preset": "^0.83.1",
"@react-native/eslint-config": "^0.83.1",
"@react-native/metro-config": "^0.83.1",
@@ -64,8 +66,9 @@
"@sentry/cli": "3.1.0",
"@sentry/react-native": "7.10.0",
"@types/events": "^3.0.3",
"@types/jest": "^30.0.0",
"@types/lodash": "4.17.23",
"@types/node": "25.0.10",
"@types/node": "^25.1.0",
"@types/react": "19.2.9",
"@typescript-eslint/eslint-plugin": "8.53.1",
"@typescript-eslint/parser": "8.53.1",
@@ -73,26 +76,10 @@
"eslint": "8.57.1",
"eslint-plugin-react": "7.37.5",
"eslint-plugin-react-hooks": "7.0.1",
"jest": "^29.7.0",
"metro-react-native-babel-transformer": "0.77.0",
"react-native-svg-transformer": "1.5.2",
"tslib": "2.8.1",
"typescript": "5.9.3"
},
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
]
},
"overrides": {
"@babel/preset-typescript": "7.23.3",
"@babel/plugin-transform-typescript": "7.23.6",
"@babel/plugin-syntax-typescript": "7.23.3",
"@babel/types": "7.23.6"
}
}
+1964 -507
View File
File diff suppressed because it is too large Load Diff
+45
View File
@@ -0,0 +1,45 @@
import fs from 'fs';
import path from 'path';
import { localeGetters } from './index';
describe('Localisation', () => {
it('should have a language getter for every locale file', () => {
// Get all locale directories
const langDir = path.join(__dirname, 'lang');
const localeDirectories = fs.readdirSync(langDir, { withFileTypes: true })
.filter((dirent: fs.Dirent) => dirent.isDirectory())
.map((dirent: fs.Dirent) => dirent.name);
// Get all getter keys
const getterKeys = Object.keys(localeGetters);
// Check each locale directory has a corresponding getter
const missingGetters: string[] = [];
for (const dir of localeDirectories) {
// Check if there's a locale.json file in this directory
const localeFilePath = path.join(langDir, dir, 'locale.json');
if (fs.existsSync(localeFilePath)) {
// Check if this locale has a getter (some use dashes instead of underscores)
const hasGetter = getterKeys.some(key =>
key === dir ||
key === dir.replace(/_/g, '-') ||
key.replace(/-/g, '_') === dir
);
if (!hasGetter) {
missingGetters.push(dir);
}
}
}
if (missingGetters.length > 0) {
throw new Error(
`Missing language getters for the following locales: ${missingGetters.join(', ')}\n` +
`Please add them to the localeGetters object in src/localisation/index.ts`
);
}
expect(missingGetters).toHaveLength(0);
});
});
+1 -1
View File
@@ -5,7 +5,7 @@ import { LocaleKeys } from './types';
const i18n = new I18n();
// Lazy loaders for locale
const localeGetters: Record<string, () => object> = {
export const localeGetters: Record<string, () => object> = {
bg: () => require('./lang/bg/locale.json'),
ca: () => require('./lang/ca/locale.json'),
cs: () => require('./lang/cs/locale.json'),
+1 -1
View File
@@ -1,7 +1,7 @@
{
"extends": "@react-native/typescript-config",
"compilerOptions": {
"types": [],
"types": ["jest", "node"],
"baseUrl": "./src",
"paths": {
"@/*": [