Class: YamlValidator

Inherits:
Object
  • Object
show all
Defined in:
lib/yaml-validator.rb,
lib/yaml-validator/version.rb

Constant Summary collapse

VERSION =
"0.1.9"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root_path, options = {}) ⇒ YamlValidator

Returns a new instance of YamlValidator.



11
12
13
14
15
# File 'lib/yaml-validator.rb', line 11

def initialize(root_path, options = {})
  @options = options
  @root_path = root_path
  @locked_keys = LockedKeys.new(@root_path) unless @root_path.nil?
end

Class Method Details

.find_key_in_yaml_object(full_key, yaml_object) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/yaml-validator.rb', line 124

def self.find_key_in_yaml_object(full_key, yaml_object)
  position = yaml_object
  full_key.split('.').each do |key|
    return nil unless position.is_a? Hash
    position = position[key]
  end
  
  if position.is_a? String or position.is_a? Symbol
    position
  else
    nil
  end
end

Instance Method Details

#enObject



17
18
19
20
21
22
23
24
25
# File 'lib/yaml-validator.rb', line 17

def en
  return @en unless @en.nil?

  fullpath = File.join(@root_path, 'en.yml')
  return nil unless File.readable?(fullpath)

  @en = YAML.load_file(fullpath)['en']
  @en = Helpers.normalize_yaml(@en)
end

#en_with_varsObject



27
28
29
30
# File 'lib/yaml-validator.rb', line 27

def en_with_vars
  return nil if en.nil?
  @en_with_vars ||= get_all_variables(en)
end

#find_english_value(full_key) ⇒ Object



156
157
158
# File 'lib/yaml-validator.rb', line 156

def find_english_value(full_key)
  self.class.find_key_in_yaml_object(full_key, en)
end

#find_missing_pluralizations(filename, yaml_object) ⇒ Object



119
120
121
122
# File 'lib/yaml-validator.rb', line 119

def find_missing_pluralizations(filename, yaml_object)
  language = File.basename(filename, '.*')
  PluralizationValidator.validate(language, yaml_object)
end

#find_missing_translations(yaml_object) ⇒ Object



98
99
100
# File 'lib/yaml-validator.rb', line 98

def find_missing_translations(yaml_object)
  find_missing_translations_in_en_object('', en, yaml_object)
end

#find_missing_translations_in_en_object(full_key, en_yaml_object, yaml_object) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/yaml-validator.rb', line 102

def find_missing_translations_in_en_object(full_key, en_yaml_object, yaml_object)
  return [] if en_yaml_object.nil?
  errors = []
  
  en_yaml_object.each do |key, value|
    full_subkey = (full_key.empty?) ? key : "#{full_key}.#{key}"
    if value.is_a? String or value.is_a? Symbol
      if self.class.find_key_in_yaml_object(full_subkey, yaml_object).nil?
        errors << "missing translation for #{full_subkey} ('#{value}')"
      end
    else
      errors.concat find_missing_translations_in_en_object(full_subkey, value, yaml_object)
    end
  end
  errors
end

#find_unsanitized_html(filename, yaml_object) ⇒ Object



239
240
241
242
# File 'lib/yaml-validator.rb', line 239

def find_unsanitized_html(filename, yaml_object)
  language = File.basename(filename, '.*')
  SanitizedHtmlValidator.validate(language, yaml_object)
end

#get_all_variables(yaml_object) ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/yaml-validator.rb', line 219

def get_all_variables(yaml_object)
  return {} if yaml_object.nil?
  with_vars = {}
  
  yaml_object.each do |key, value|
    if value.is_a? String
      with_vars[key] = identify_variables(value)
    elsif value.is_a? Symbol
      with_vars[key] = {}
    else
      with_vars[key] = get_all_variables(value)
    end
  end
  with_vars
end

#get_key_en_vars(full_key) ⇒ Object



205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/yaml-validator.rb', line 205

def get_key_en_vars(full_key)
  position = en_with_vars
  full_key.split('.').each do |key|
    return nil if position.is_a? Array
    return nil if position.nil?
    position = position[key]
  end
  if position.is_a? Array
    position
  else
    nil
  end
end

#identify_variables(string) ⇒ Object



235
236
237
# File 'lib/yaml-validator.rb', line 235

def identify_variables(string)
  string.scan(/%\{([^}]+)\}/).map(&:first)
end

#validateObject



32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/yaml-validator.rb', line 32

def validate()
  if en_with_vars.nil?
    return ["no en.yml file in the directory (an en.yml file is required as reference)"]
  end
  yml_files = File.join(@root_path, '*.yml')
  errors = []
  Dir[yml_files].each do |filename|
    next if File.basename(filename) == 'en.yml'
    errors.concat validate_yaml(filename)
  end
  errors
end

#validate_item(full_key, value, is_pluralization = false) ⇒ Object



138
139
140
141
142
143
# File 'lib/yaml-validator.rb', line 138

def validate_item(full_key, value, is_pluralization = false)
  errors = validate_item_vars(full_key, value, is_pluralization)
  errors.concat validate_item_characters(full_key, value)
  errors.concat validate_locked_key(full_key, value)
  errors
end

#validate_item_characters(full_key, value) ⇒ Object



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/yaml-validator.rb', line 160

def validate_item_characters(full_key, value)
  bad_chars = ''
  bad_chars_found = []
  bad_chars.each_char do |ch|
    if value.include? ch
      bad_chars_found << ch
    end
  end

  if bad_chars_found.any?
    return ["#{full_key}: bad characters (#{bad_chars_found.join(', ')} ) in '#{value}'"]
  else
    return []
  end
end

#validate_item_vars(full_key, value, is_pluralization = false) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/yaml-validator.rb', line 176

def validate_item_vars(full_key, value, is_pluralization = false)
  real_vars = get_key_en_vars(full_key)
  if real_vars.nil?
    if is_pluralization
      return []
    else
      return ["#{full_key} doesn't exist in en.yml"]
    end
  end

  syntax_error = /(^|[^%]){[^}]+}%?/.match(value)
  unless syntax_error.nil?
    return [
      "#{full_key}: invalid syntax '#{syntax_error}'"
    ]
  end

  used_vars = identify_variables(value)

  errors = []

  used_vars.each do |var|
    unless real_vars.include? var
      errors << "#{full_key}: missing variable '#{var}' (available options: #{real_vars.join(', ')})"
    end
  end
  errors
end

#validate_locked_key(full_key, value) ⇒ Object



145
146
147
148
149
150
151
152
153
154
# File 'lib/yaml-validator.rb', line 145

def validate_locked_key(full_key, value)
  errors = []
  if @locked_keys.locked? full_key
    locked_value = find_english_value(full_key)
    if locked_value != value
      errors << "#{full_key}: locked key value changed from '#{locked_value}' to '#{value}'"
    end
  end
  errors
end

#validate_root_language(yaml_object, file_name) ⇒ Object



71
72
73
74
75
76
77
78
79
80
# File 'lib/yaml-validator.rb', line 71

def validate_root_language(yaml_object, file_name)
  errors = []

  lang = yaml_object.keys.first
  if lang != file_name.split(".").first
    errors << "invalid root language (#{lang})"
  end

  errors
end

#validate_yaml(filepath) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/yaml-validator.rb', line 45

def validate_yaml(filepath)
  filename = File.basename(filepath)
  
  begin
    yaml_object = YAML.load_file(filepath)
  rescue Psych::SyntaxError => e
    return [e.message.sub(/^\([^)]+\)/, filename)]
  end
  
  errors = validate_root_language(yaml_object, File.basename(filename))

  yaml_object = yaml_object[yaml_object.keys[0]]
  yaml_object = Helpers.normalize_yaml(yaml_object)
  errors += validate_yaml_object('', yaml_object)
  if @options[:missing]
    errors.concat find_missing_translations(yaml_object)
    errors.concat find_missing_pluralizations(filename, yaml_object)
  end

  if @options[:sanitize]
    errors.concat find_unsanitized_html(filename, yaml_object)
  end
  
  errors.map { |err| "#{filename}: #{err}" }
end

#validate_yaml_object(full_key, yaml_object) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/yaml-validator.rb', line 82

def validate_yaml_object(full_key, yaml_object)
  return [] if yaml_object.nil?
  errors = []
  is_pluralization = Helpers.pluralization? yaml_object
  
  yaml_object.each do |key, value|
    full_subkey = (full_key.empty?) ? key : "#{full_key}.#{key}"
    if value.is_a? String
      errors.concat validate_item(full_subkey, value, is_pluralization)
    else
      errors.concat validate_yaml_object(full_subkey, value)
    end
  end
  errors
end