Skip to content

Commit

Permalink
Add localization responses and error messages (#93)
Browse files Browse the repository at this point in the history
* Add localization responses and error messages

* Add test coverage for change_locale method
  • Loading branch information
sarslanoglu authored May 18, 2021
1 parent a3c012f commit 68d0db0
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .hound.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
rubocop:
version: 0.83.0
version: 1.5.2
config_file: .rubocop.yml
3 changes: 2 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ AllCops:
- 'Gemfile'
- 'turkish_cities.gemspec'
NewCops: enable
SuggestExtensions: false
Layout/LineLength:
Max: 120
Metrics/AbcSize:
Max: 20
Metrics/BlockLength:
ExcludedMethods: ['describe', 'context']
IgnoredMethods: ['describe', 'context']
Metrics/MethodLength:
Max: 15
Style/Documentation:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## master

### New features

* [#68](https://github.com/sarslanoglu/turkish_cities/issues/68): Add localization for all method responses and errors

## 0.4.0 (2021-04-25)

### New features
Expand Down
24 changes: 12 additions & 12 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ PATH
GEM
remote: https://rubygems.org/
specs:
ast (2.4.1)
ast (2.4.2)
concurrent-ruby (1.1.6)
coveralls (0.8.23)
json (>= 1.8, < 3)
Expand All @@ -20,12 +20,12 @@ GEM
i18n (1.8.5)
concurrent-ruby (~> 1.0)
json (2.3.0)
parallel (1.20.0)
parser (2.7.2.0)
parallel (1.20.1)
parser (3.0.1.1)
ast (~> 2.4.1)
rainbow (3.0.0)
regexp_parser (1.8.2)
rexml (3.2.4)
regexp_parser (2.1.1)
rexml (3.2.5)
rspec (3.10.0)
rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0)
Expand All @@ -39,18 +39,18 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-support (3.10.0)
rubocop (1.3.1)
rubocop (1.5.2)
parallel (~> 1.10)
parser (>= 2.7.1.5)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8)
regexp_parser (>= 1.8, < 3.0)
rexml
rubocop-ast (>= 1.1.1)
rubocop-ast (>= 1.2.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (1.1.1)
parser (>= 2.7.1.5)
ruby-progressbar (1.10.1)
rubocop-ast (1.5.0)
parser (>= 3.0.1.1)
ruby-progressbar (1.11.0)
simplecov (0.16.1)
docile (~> 1.1)
json (>= 1.8, < 3)
Expand All @@ -71,7 +71,7 @@ DEPENDENCIES
bundler (~> 2.2.16)
coveralls (~> 0.8.23)
rspec (~> 3.10.0)
rubocop (~> 1.3.1)
rubocop (~> 1.5.2)
turkish_cities!

BUNDLED WITH
Expand Down
26 changes: 22 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ https://rubygems.org/gems/turkish_cities

## Table of Contents
* [Installation](#installation)
* [Localization](#localization)
* [Documentation](#documentation)
* [Finding city name by plate number](#finding-city-name-by-plate-number)
* [Finding city name by phone code](#finding-city-name-by-phone-code)
Expand Down Expand Up @@ -63,6 +64,24 @@ and run
$ bundle
```

## Localization

Currently gem supports two different languages, Turkish and English. English is default, if no action taken.

Language can be easily changed by ```change_locale``` method. Valid parameters are 'tr' for Turkish and 'en' for English.

```rb
TurkishCities.change_locale('tr') # => "Dil Türkçe olarak ayarlandı."
```

After changing language all errors and result sets will be in desired language

```rb
TurkishCities.list_districts('Eskişehirrr') # => "'Eskişehirrr' ile bir şehir bulunamadı"
TurkishCities.distance_between('kirsehir', 'Ordu', 'land')
# => [533, "Kırşehir ile Ordu arasındaki karayolu mesafesi 533 km"]
```

## Documentation

With using irb just require gem and start using
Expand Down Expand Up @@ -319,17 +338,16 @@ https://www.kgm.gov.tr/SiteCollectionDocuments/KGMdocuments/Root/Uzakliklar/ilme

| Ruby Version | Supported |
| ------------ | ------------------ |
| 2.7.1 | :white_check_mark: |
| 2.6.6 | :white_check_mark: |
| 2.5.8 | :white_check_mark: |
| 2.7.x | :white_check_mark: |
| 2.6.x | :white_check_mark: |
| 2.5.x | :white_check_mark: |
| < 2.5.1 | :x: |

- TurkishCities heavily depends on ```:turkic``` case mapping support of Ruby string downcase method. Below Ruby version 2.5.1 some functions will run buggy/false or even won't run at all.

## Roadmap

- Add missing sea travel method
- Add localization to gem
- Refactor tests (separate test suites with more edge case tests)

## Contributing
Expand Down
17 changes: 17 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
en:
description_text:
air_travel: "Air travel distance between %{first_city} and %{second_city} is %{distance} km. Estimated air travel would take %{duration} minutes"
land_travel: "Land travel distance between %{first_city} and %{second_city} is %{distance} km"
errors:
cities_not_found_error: "Couldn't find cities combination with '%{first}/%{second}'"
city_not_found_error: "Couldn't find city name with '%{input}'"
district_not_found_error: "Couldn't find district name with '%{district_input}' of '%{city_input}'"
not_even_input: "Given value [%{input}] must be an even number"
outside_bounds: "Given value [%{input}] is outside bounds of %{min} to %{max}"
postcode_not_found_error: "Couldn't find any subdistrict with postcode '%{postcode_input}'"
subdistrict_not_found_error: "Couldn't find subdistrict with '%{subdistrict_input}' of '%{district_input}'/'%{city_input}'"
unsupported_travel_method: "Travel method '%{input}' is unsupported"
language:
errors:
unsupported_language_code: "Unsupported language code. Please use 'tr' for Turkish, 'en' for English"
success: "Language set to English"
17 changes: 17 additions & 0 deletions config/locales/tr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
tr:
description_text:
air_travel: "%{first_city} ile %{second_city} arasındaki havayolu mesafesi %{distance} km. Tahmini uçuş süresi %{duration} dakikadır"
land_travel: "%{first_city} ile %{second_city} arasındaki karayolu mesafesi %{distance} km"
errors:
cities_not_found_error: "'%{first}/%{second}' ile şehir kombinasyonu bulunamadı"
city_not_found_error: "'%{input}' ile bir şehir bulunamadı"
district_not_found_error: "'%{city_input}' şehrine ait '%{district_input}' ilçesi ile bir kayıt bulunamadı"
not_even_input: "Girilen değer [%{input}] çift sayı olmalı"
outside_bounds: "Girilen değer [%{input}] %{min} ile %{max} değerleri dışında"
postcode_not_found_error: "'%{postcode_input}' posta kodu ile kayıt bulunamadı"
subdistrict_not_found_error: "'%{subdistrict_input}' ile '%{district_input}'/'%{city_input}' ait bir kayıt bulunamdı"
unsupported_travel_method: "'%{input}' yolculuk methodu desteklenmiyor"
language:
errors:
unsupported_language_code: "Desteklenmeyen dil kodu. Lütfen Türkçe için 'tr', İngilizce için 'en' kullanınız"
success: "Dil Türkçe olarak ayarlandı"
19 changes: 17 additions & 2 deletions lib/turkish_cities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,22 @@
require_relative '../lib/turkish_cities/postcode'
require_relative '../lib/turkish_cities/version'

require 'i18n'

I18n.load_path << Dir["#{File.expand_path('config/locales')}/*.yml"]

class TurkishCities
PLATE_NUMBER = 'plate_number'
PHONE_CODE = 'phone_code'

def self.change_locale(language_code)
if %w[en tr].include?(language_code)
I18n.locale = language_code.to_sym
return I18n.t('language.success')
end
I18n.t('language.errors.unsupported_language_code')
end

def self.find_name_by_plate_number(plate_number)
City.new.find_by_id(plate_number)
end
Expand All @@ -16,11 +31,11 @@ def self.find_name_by_phone_code(phone_code)
end

def self.find_plate_number_by_name(city_name)
City.new.find_by_name(city_name, 'plate_number')
City.new.find_by_name(city_name, self::PLATE_NUMBER)
end

def self.find_phone_code_by_name(city_name)
City.new.find_by_name(city_name, 'phone_code')
City.new.find_by_name(city_name, self::PHONE_CODE)
end

def self.list_cities(options = {})
Expand Down
4 changes: 1 addition & 3 deletions lib/turkish_cities/city.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
class City
include DecomposerHelper

I18n.enforce_available_locales = false

file_path = File.join(File.dirname(__FILE__), 'data/cities.yaml')
CITY_LIST = YAML.load_file(file_path)

Expand Down Expand Up @@ -67,7 +65,7 @@ def list_districts(city_name)
def check_phone_code(input)
return if input.to_i.even?

raise ArgumentError, "Given value [#{input}] must be an even number."
raise ArgumentError, I18n.t('errors.not_even_input', input: input)
end

def filter_metropolitan_municipalities(city_list)
Expand Down
2 changes: 1 addition & 1 deletion lib/turkish_cities/data/neighborhoods_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module NeighborhoodsParser
end

mahalle = []
data_array[3].downcase(:turkic).strip.split(' ').each do |word|
data_array[3].downcase(:turkic).strip.split.each do |word|
if word[0] == '('
word[1] = word[1].capitalize!(:turkic) unless word[1].to_i.to_s == word[1]
else
Expand Down
11 changes: 7 additions & 4 deletions lib/turkish_cities/distance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,14 @@ def distance_time_estimation(air_distance)

def description_text(travel_method, city_array, result_set)
if travel_method == 'Air'
return "#{travel_method} travel distance between #{city_array[0]['name']} and #{city_array[1]['name']} is " \
"#{result_set[0]} km. Estimated air travel would take #{result_set[1]} minutes."
return I18n.t('description_text.air_travel', first_city: city_array[0]['name'],
second_city: city_array[1]['name'],
distance: result_set[0],
duration: result_set[1])
end

"#{travel_method} travel distance between #{city_array[0]['name']} and #{city_array[1]['name']} is " \
"#{result_set[0]} km."
I18n.t('description_text.land_travel', first_city: city_array[0]['name'],
second_city: city_array[1]['name'],
distance: result_set[0])
end
end
16 changes: 9 additions & 7 deletions lib/turkish_cities/helpers/decomposer_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ module DecomposerHelper
def check_input_range(input, min, max)
return if input.to_i.between?(min, max)

raise RangeError, "Given value [#{input}] is outside bounds of #{min} to #{max}."
raise RangeError, I18n.t('errors.outside_bounds', input: input, min: min, max: max)
end

def city_not_found_error(input)
"Couldn't find city name with '#{input}'"
I18n.t('errors.city_not_found_error', input: input)
end

def cities_not_found_error(first, second)
"Couldn't find cities combination with '#{first}/#{second}'"
I18n.t('errors.cities_not_found_error', first: first, second: second)
end

def convert_chars(string)
Expand All @@ -35,11 +35,11 @@ def create_file_path(city_name)
end

def district_not_found_error(district_input, city_input)
"Couldn't find district name with '#{district_input}' of '#{city_input}'"
I18n.t('errors.district_not_found_error', district_input: district_input, city_input: city_input)
end

def postcode_not_found_error(postcode_input)
"Couldn't find any subdistrict with postcode '#{postcode_input}'"
I18n.t('errors.postcode_not_found_error', postcode_input: postcode_input)
end

def prepare_city_list(city_list, options)
Expand All @@ -64,6 +64,7 @@ def prepare_city_list(city_list, options)

def sort_alphabetically(list, options = nil)
turkish_alphabet = ' -0123456789abcçdefgğhıijklmnoöprsştuüvyz'

list.sort_by do |item|
item_to_sort = if options.nil? || options[:with].nil?
item
Expand All @@ -75,7 +76,8 @@ def sort_alphabetically(list, options = nil)
end

def subdistrict_not_found_error(subdistrict_input, district_input, city_input)
"Couldn't find subdistrict with '#{subdistrict_input}' of '#{district_input}'/'#{city_input}'"
I18n.t('errors.subdistrict_not_found_error', subdistrict_input: subdistrict_input, district_input: district_input,
city_input: city_input)
end

private
Expand All @@ -99,6 +101,6 @@ def add_metropolitan_municipality_if_requested(result, city, options = nil)
end

def unsupported_travel_method(input)
"Travel method '#{input}' is unsupported"
I18n.t('errors.unsupported_travel_method', input: input)
end
end
Loading

0 comments on commit 68d0db0

Please sign in to comment.