195 lines
5.6 KiB
Ruby
195 lines
5.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "rails_helper"
|
|
require "i18n/duplicate_key_finder"
|
|
|
|
def extract_locale(path)
|
|
path[/\.([^.]{2,})\.yml$/, 1]
|
|
end
|
|
|
|
PLURALIZATION_KEYS ||= ['zero', 'one', 'two', 'few', 'many', 'other']
|
|
ENGLISH_KEYS ||= ['one', 'other']
|
|
|
|
def find_pluralizations(hash, parent_key = '', pluralizations = Hash.new)
|
|
hash.each do |key, value|
|
|
if Hash === value
|
|
current_key = parent_key.blank? ? key : "#{parent_key}.#{key}"
|
|
find_pluralizations(value, current_key, pluralizations)
|
|
elsif PLURALIZATION_KEYS.include? key
|
|
pluralizations[parent_key] = hash
|
|
end
|
|
end
|
|
|
|
pluralizations
|
|
end
|
|
|
|
def is_yaml_compatible?(english, translated)
|
|
english.each do |k, v|
|
|
if translated.has_key?(k)
|
|
if Hash === v
|
|
if Hash === translated[k]
|
|
return false unless is_yaml_compatible?(v, translated[k])
|
|
end
|
|
else
|
|
return false unless v.class == translated[k].class
|
|
end
|
|
end
|
|
end
|
|
|
|
true
|
|
end
|
|
|
|
def each_translation(hash, parent_key = '', &block)
|
|
hash.each do |key, value|
|
|
current_key = parent_key.blank? ? key : "#{parent_key}.#{key}"
|
|
|
|
if Hash === value
|
|
each_translation(value, current_key, &block)
|
|
else
|
|
yield(current_key, value.to_s)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "i18n integrity checks" do
|
|
|
|
it 'has an i18n key for each Trust Levels' do
|
|
TrustLevel.all.each do |ts|
|
|
expect(ts.name).not_to match(/translation missing/)
|
|
end
|
|
end
|
|
|
|
it "has an i18n key for each Site Setting" do
|
|
SiteSetting.all_settings.each do |s|
|
|
next if s[:setting][/^test_/]
|
|
expect(s[:description]).not_to match(/translation missing/)
|
|
end
|
|
end
|
|
|
|
it "has an i18n key for each Badge description" do
|
|
Badge.where(system: true).each do |b|
|
|
expect(b.long_description).to be_present
|
|
expect(b.description).to be_present
|
|
end
|
|
end
|
|
|
|
Dir["#{Rails.root}/config/locales/{client,server}.*.yml"].each do |path|
|
|
it "does not contain invalid interpolation keys for '#{path}'" do
|
|
matches = File.read(path).scan(/%\{([^a-zA-Z\s]+)\}|\{\{([^a-zA-Z\s]+)\}\}/)
|
|
matches.flatten!
|
|
matches.compact!
|
|
matches.uniq!
|
|
expect(matches).to eq([])
|
|
end
|
|
end
|
|
|
|
Dir["#{Rails.root}/config/locales/client.*.yml"].each do |path|
|
|
it "has valid client YAML for '#{path}'" do
|
|
yaml = YAML.load_file(path)
|
|
locale = extract_locale(path)
|
|
|
|
expect(yaml.keys).to eq([locale])
|
|
|
|
expect(yaml[locale]["js"]).to be
|
|
|
|
if !LocaleSiteSetting.fallback_locale(locale)
|
|
expect(yaml[locale]["admin_js"]).to be
|
|
expect(yaml[locale]["wizard_js"]).to be
|
|
end
|
|
end
|
|
end
|
|
|
|
Dir["#{Rails.root}/**/locale*/*.en.yml"].each do |english_path|
|
|
english_yaml = YAML.load_file(english_path)["en"]
|
|
|
|
context(english_path) do
|
|
it "has no duplicate keys" do
|
|
english_duplicates = DuplicateKeyFinder.new.find_duplicates(english_path)
|
|
expect(english_duplicates).to be_empty
|
|
end
|
|
|
|
context "pluralizations" do
|
|
wrong_keys = []
|
|
invald_one_keys = []
|
|
|
|
find_pluralizations(english_yaml).each do |key, hash|
|
|
next if key["messages.restrict_dependent_destroy"]
|
|
|
|
wrong_keys << key if hash.keys.sort != ENGLISH_KEYS
|
|
|
|
if one_value = hash['one']
|
|
invald_one_keys << key if one_value.include?('1') && !one_value.match?(/%{count}|{{count}}/)
|
|
end
|
|
end
|
|
|
|
it "has valid pluralizations keys" do
|
|
keys = wrong_keys.join("\n")
|
|
expect(wrong_keys).to be_empty, <<~MSG
|
|
Pluralized strings must have only the sub-keys 'one' and 'other'.
|
|
The following keys have missing or additional keys:\n\n#{keys}
|
|
MSG
|
|
end
|
|
|
|
it "should use %{count} instead of 1 in 'one' keys" do
|
|
keys = invald_one_keys.join(".one\n")
|
|
expect(invald_one_keys).to be_empty, <<~MSG
|
|
The following keys contain the number 1 instead of the interpolation key %{count}:\n\n#{keys}
|
|
MSG
|
|
end
|
|
end
|
|
|
|
context "valid translations" do
|
|
invalid_relative_links = {}
|
|
invalid_relative_image_sources = {}
|
|
|
|
each_translation(english_yaml) do |key, value|
|
|
if value.match?(/href\s*=\s*["']\/[^\/]|\]\(\/[^\/]/i)
|
|
invalid_relative_links[key] = value
|
|
elsif value.match?(/src\s*=\s*["']\/[^\/]/i)
|
|
invalid_relative_image_sources[key] = value
|
|
end
|
|
end
|
|
|
|
it "uses %{base_url} or %{base_path} for relative links" do
|
|
keys = invalid_relative_links.keys.join("\n")
|
|
expect(invalid_relative_links).to be_empty, "The following keys have relative links, but do not start with %{base_url} or %{base_path}:\n\n#{keys}"
|
|
end
|
|
|
|
it "uses %{base_url} or %{base_path} for relative image src" do
|
|
keys = invalid_relative_image_sources.keys.join("\n")
|
|
expect(invalid_relative_image_sources).to be_empty, "The following keys have relative image sources, but do not start with %{base_url} or %{base_path}:\n\n#{keys}"
|
|
end
|
|
end
|
|
end
|
|
|
|
Dir[english_path.sub(".en.yml", ".*.yml")].each do |path|
|
|
next if path[".en.yml"]
|
|
|
|
context(path) do
|
|
locale = extract_locale(path)
|
|
yaml = YAML.load_file(path)
|
|
|
|
it "has no duplicate keys" do
|
|
duplicates = DuplicateKeyFinder.new.find_duplicates(path)
|
|
expect(duplicates).to be_empty
|
|
end
|
|
|
|
it "does not overwrite another locale" do
|
|
expect(yaml.keys).to eq([locale])
|
|
end
|
|
|
|
unless path["transliterate"]
|
|
|
|
it "is compatible with english" do
|
|
expect(is_yaml_compatible?(english_yaml, yaml)).to eq(true)
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
end
|