Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions lib/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,28 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/

const environmentLocale = Intl.DateTimeFormat().resolvedOptions().locale

/**
* Returns the user's locale
*/
export function getLocale(): string {
return document.documentElement.dataset.locale || 'en'
return document.documentElement.dataset.locale || environmentLocale.replaceAll(/-/g, '_')
}

/**
* Returns user's locale in canonical form
* E.g. `en-US` instead of `en_US`
*/
export function getCanonicalLocale(): string {
return getLocale().replace(/_/g, '-')
return getLocale().replaceAll(/_/g, '-')
}

/**
* Returns the user's language
*/
export function getLanguage(): string {
return document.documentElement.lang || 'en'
return document.documentElement.lang || navigator.language
}

/**
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
"dev": "vite --mode development build --watch",
"lint": "eslint .",
"lint:fix": "eslint --fix lib tests",
"test": "vitest run",
"test:coverage": "vitest run --coverage",
"test:watch": "vitest watch"
"test": "LANG=en-US vitest run",
"test:coverage": "LANG=en-US vitest run --coverage",
"test:watch": "LANG=en-US vitest watch"
},
"browserslist": [
"extends @nextcloud/browserslist-config"
Expand Down
69 changes: 36 additions & 33 deletions tests/locale.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { afterEach, beforeEach, describe, expect, it, test } from 'vitest'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import {
getCanonicalLocale,
getLanguage,
Expand All @@ -13,54 +13,57 @@ import {
const setLocale = (locale: string) => document.documentElement.setAttribute('data-locale', locale)
const setLanguage = (lang: string) => document.documentElement.setAttribute('lang', lang)

describe('getCanonicalLocale', () => {
afterEach(() => {
setLocale('')
describe('getLanguage', () => {
it('returns the set language as it is', () => {
setLanguage('de-DE')
expect(getLanguage()).toEqual('de-DE')
})

it('Returns primary locales as is', () => {
setLocale('de')
expect(getCanonicalLocale()).toEqual('de')
setLocale('zu')
expect(getCanonicalLocale()).toEqual('zu')
it('returns the navigator language if no language is set', () => {
const spy = vi.spyOn(navigator, 'language', 'get')
spy.mockImplementationOnce(() => 'ar-EG')

setLanguage('')
expect(getLanguage()).toEqual('ar-EG')
expect(spy).toHaveBeenCalledOnce()
})
})

it('Returns extended locales with hyphens', () => {
setLocale('az_Cyrl_AZ')
expect(getCanonicalLocale()).toEqual('az-Cyrl-AZ')
describe('getLocale', () => {
it('returns the set locale as it is with underscore', () => {
setLocale('de_DE')
expect(getCanonicalLocale()).toEqual('de-DE')
expect(getLocale()).toEqual('de_DE')
})

it('returns the environment locale with underscore if no locale is set', () => {
setLocale('')
expect(getLocale()).toEqual(process.env.LANG?.replaceAll('-', '_'))
})
})

test('getLanguage', () => {
document.documentElement.removeAttribute('lang')
// Expect fallback
expect(getLanguage()).toBe('en')
setLanguage('')
expect(getLanguage()).toBe('en')
describe('getCanonicalLocale', () => {
it('returns the set locale with hyphen', () => {
setLocale('de_DE')
expect(getCanonicalLocale()).toEqual('de-DE')
})

// Expect value
setLanguage('zu')
expect(getLanguage()).toBe('zu')
})
it('returns the set locale with multiple hyphen', () => {
setLocale('az_Cyrl_AZ')
expect(getCanonicalLocale()).toEqual('az-Cyrl-AZ')
})

test('getLocale', () => {
document.documentElement.removeAttribute('data-locale')
// Expect fallback
expect(getLocale()).toBe('en')
setLocale('')
expect(getLocale()).toBe('en')
it('returns the environment locale with hyphen if no locale is set', () => {
expect(process.env.LANG).not.toBe('')

// Expect value
setLocale('de_DE')
expect(getLocale()).toBe('de_DE')
setLocale('')
expect(getCanonicalLocale()).toEqual(process.env.LANG)
})
})

describe('isRTL', () => {
beforeEach(() => document.documentElement.removeAttribute('data-locale'))

it('fallsback to English which is LTR', () => {
it('falls back to English which is LTR', () => {
// Expect fallback which is English = LTR
expect(isRTL()).toBe(false)
})
Expand Down