diff --git a/README.md b/README.md index 2bb0ab7dae..389fdae4b8 100644 --- a/README.md +++ b/README.md @@ -169,9 +169,7 @@ Faker::Config.locale = 'es' Faker::Config.locale = :es ``` -Note: Overriding the default locale might not be thread-safe. See [Locale setting can be ignored #2563](https://github.com/faker-ruby/faker/issues/2563) for more details. - -To override Faker's locales, +To override Faker's locales, and set it on threaded server environments check out the [locales README](lib/locales/README.md). ### Minitest and Faker >= 2.22 diff --git a/lib/locales/README.md b/lib/locales/README.md index 13abb32c46..8202d68aef 100644 --- a/lib/locales/README.md +++ b/lib/locales/README.md @@ -9,7 +9,7 @@ Here's how to set it: Faker::Config.locale = 'zh-CN' ``` -It works so that once the Faker locale is set to a different location, the translate method will check that .yml file for an equivalent and use that data. If it doesn't exist, it defaults back to English. It uses the "i18n" gem to do this. +It works so that once the Faker locale is set to a different location, the translate method will check that `.yml` file for an equivalent and use that data. If it doesn't exist, it defaults back to English. It uses the [I18n](https://github.com/ruby-i18n/i18n) gem to do this. Using Chinese as an example, when the locale is set to Chinese and you attempt to call for hipster ipsem (which doesn't exist at the time of this writing), you will get English back. It checks the "zh-CH.yml" file, does not find "hipster" and then checks the "en.yml" file and returns a word from that array. @@ -18,7 +18,9 @@ Faker::Config.locale = 'zh-CN' Faker::Hipster.word #=> "kogi" ``` -In order to update a locale with more translation features, simply add a new field to the .yml file that corresponds to an existing piece of functionality in the "en.yml" file. In this example, that would mean providing Chinese hipster words. +## How to update a locale with more translations + +T update a locale with more translation features, simply add a new field to the .yml file that corresponds to an existing piece of functionality in the "en.yml" file. In this example, that would mean providing Chinese hipster words. ```yaml # /lib/locales/zh-CN.yml @@ -38,3 +40,17 @@ In our hypothetical example here, one would add something like this to the "test ```ruby assert Faker::Hipster.word.is_a? String ``` + +## How to set the default locale for in threaded server environments + +If you want to modify the default locale that will be used in new threads, set it in your configuration: + +```ruby +Faker::Config.default_locale = :pt +``` + +In threaded server environments, e.g., Puma, locale per thread can be set as the following: + +```ruby + Faker::Config.locale = :es +``` diff --git a/test/test_default_locale.rb b/test/test_default_locale.rb new file mode 100644 index 0000000000..c85ac3a906 --- /dev/null +++ b/test/test_default_locale.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +require_relative 'test_helper' + +class TestDefaultLocale < Test::Unit::TestCase + def test_setting_default_locale + # if locale is not set, fallback is :en + assert_equal :en, Faker::Config.locale + + # locale can be updated initially + # and it becomes the default value + # for new threads + Faker::Config.default_locale = :pt + + assert_equal :pt, Faker::Config.locale + + t1 = Thread.new do + # child thread has initial locale equal to + # latest locale set on main thread + # instead of the fallback value + assert_equal :pt, Faker::Config.locale + + # child thread can set its own locale + Faker::Config.locale = :es + + assert_equal :es, Faker::Config.locale + end + + t1.join + + # child thread won't change locale of other threads + assert_equal :pt, Faker::Config.locale + + t2 = Thread.new do + # initial default locale is copied over to new thread + assert_equal :pt, Faker::Config.locale + + Faker::Config.locale = :it + + assert_equal :it, Faker::Config.locale + end + + t2.join + + assert_equal :pt, Faker::Config.locale + + # setting this to reset the default locale for all tests + Faker::Config.default_locale = nil + + assert_equal :en, Faker::Config.locale + end + + def test_setting_default_locale_on_child_thread + # if locale is not set, fallback is :en + assert_equal :en, Faker::Config.locale + + # locale can be updated initially + # and it becomes the default value + # for new threads + Faker::Config.default_locale = :pt + + assert_equal :pt, Faker::Config.locale + + t1 = Thread.new do + # child thread has initial locale equal to + # latest locale set on main thread + # instead of the fallback value + assert_equal :pt, Faker::Config.locale + + # child thread can set the default locale + Faker::Config.default_locale = :es + + assert_equal :es, Faker::Config.locale + end + + t1.join + + # all threads now will have the same default + assert_equal :es, Faker::Config.locale + + t2 = Thread.new do + # initial default locale is copied over to new thread + assert_equal :es, Faker::Config.locale + + Faker::Config.locale = :it + + assert_equal :it, Faker::Config.locale + end + + t2.join + + assert_equal :es, Faker::Config.locale + + # setting this to reset the default locale for all tests + Faker::Config.default_locale = nil + + assert_equal :en, Faker::Config.locale + end +end