Add spec to check locale files for duplicate keys
This commit is contained in:
parent
f50ec0a86e
commit
49dc470a28
|
@ -0,0 +1,48 @@
|
|||
require 'psych'
|
||||
|
||||
class LocaleFileWalker
|
||||
protected
|
||||
|
||||
def handle_document(document)
|
||||
# we want to ignore the language (first key), so let's start at -1
|
||||
handle_nodes(document.root.children, -1, [])
|
||||
end
|
||||
|
||||
def handle_nodes(nodes, depth, parents)
|
||||
if nodes
|
||||
consecutive_scalars = 0
|
||||
nodes.each do |node|
|
||||
consecutive_scalars = handle_node(node, depth, parents, consecutive_scalars)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def handle_node(node, depth, parents, consecutive_scalars)
|
||||
node_is_scalar = node.is_a?(Psych::Nodes::Scalar)
|
||||
|
||||
if node_is_scalar
|
||||
handle_scalar(node, depth, parents) if valid_scalar?(depth, consecutive_scalars)
|
||||
elsif node.is_a?(Psych::Nodes::Alias)
|
||||
handle_alias(node, depth, parents)
|
||||
elsif node.is_a?(Psych::Nodes::Mapping)
|
||||
handle_mapping(node, depth, parents)
|
||||
handle_nodes(node.children, depth + 1, parents.dup)
|
||||
end
|
||||
|
||||
node_is_scalar ? consecutive_scalars + 1 : 0
|
||||
end
|
||||
|
||||
def valid_scalar?(depth, consecutive_scalars)
|
||||
depth >= 0 && consecutive_scalars.even?
|
||||
end
|
||||
|
||||
def handle_scalar(node, depth, parents)
|
||||
parents[depth] = node.value
|
||||
end
|
||||
|
||||
def handle_alias(node, depth, parents)
|
||||
end
|
||||
|
||||
def handle_mapping(node, depth, parents)
|
||||
end
|
||||
end
|
|
@ -1,4 +1,5 @@
|
|||
require 'spec_helper'
|
||||
require 'locale_file_walker'
|
||||
|
||||
describe "i18n integrity checks" do
|
||||
|
||||
|
@ -57,4 +58,40 @@ describe "i18n integrity checks" do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'keys in English locale files' do
|
||||
locale_files = ['config/locales', 'plugins/**/locales']
|
||||
.product(['server.en.yml', 'client.en.yml'])
|
||||
.collect { |dir, filename| Dir["#{Rails.root}/#{dir}/#{filename}"] }
|
||||
.flatten
|
||||
.map { |path| Pathname.new(path).relative_path_from(Rails.root) }
|
||||
|
||||
class DuplicateKeyFinder < LocaleFileWalker
|
||||
def find_duplicates(filename)
|
||||
@keys_with_count = {}
|
||||
|
||||
document = Psych.parse_file(filename)
|
||||
handle_document(document)
|
||||
|
||||
@keys_with_count.delete_if { |key, count| count <= 1 }.keys
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def handle_scalar(node, depth, parents)
|
||||
super(node, depth, parents)
|
||||
|
||||
key = parents.join('.')
|
||||
@keys_with_count[key] = @keys_with_count.fetch(key, 0) + 1
|
||||
end
|
||||
end
|
||||
|
||||
locale_files.each do |path|
|
||||
context path do
|
||||
it 'has no duplicate keys' do
|
||||
duplicates = DuplicateKeyFinder.new.find_duplicates("#{Rails.root}/#{path}")
|
||||
expect(duplicates).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue