yaml-validator 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +26 -0
- data/README.md +40 -0
- data/Rakefile +4 -0
- data/bin/yaml-validator +15 -0
- data/lib/yaml-validator.rb +98 -0
- data/lib/yaml-validator/version.rb +3 -0
- data/spec/fixtures/inconsistent_types/en.yml +6 -0
- data/spec/fixtures/inconsistent_types/he.yml +9 -0
- data/spec/fixtures/invalid_yml/invalid.yml +1 -0
- data/spec/fixtures/wrong_variables/en.yml +3 -0
- data/spec/fixtures/wrong_variables/he.yml +3 -0
- data/spec/yaml-validator_spec.rb +138 -0
- data/yaml-validator.gemspec +22 -0
- metadata +105 -0
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --format doc
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
yaml-validator (0.0.1)
|
5
|
+
rake
|
6
|
+
rspec
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
diff-lcs (1.1.3)
|
12
|
+
rake (10.0.3)
|
13
|
+
rspec (2.12.0)
|
14
|
+
rspec-core (~> 2.12.0)
|
15
|
+
rspec-expectations (~> 2.12.0)
|
16
|
+
rspec-mocks (~> 2.12.0)
|
17
|
+
rspec-core (2.12.2)
|
18
|
+
rspec-expectations (2.12.1)
|
19
|
+
diff-lcs (~> 1.1.3)
|
20
|
+
rspec-mocks (2.12.2)
|
21
|
+
|
22
|
+
PLATFORMS
|
23
|
+
ruby
|
24
|
+
|
25
|
+
DEPENDENCIES
|
26
|
+
yaml-validator!
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
YAML Validator
|
2
|
+
==============
|
3
|
+
|
4
|
+
Validates .yml locale files for Ruby on Rails projects.
|
5
|
+
|
6
|
+
What does it validate?
|
7
|
+
----------------------
|
8
|
+
|
9
|
+
Given the following file tree:
|
10
|
+
|
11
|
+
```
|
12
|
+
config/
|
13
|
+
locales/
|
14
|
+
en.yml
|
15
|
+
he.yml
|
16
|
+
nl.yml
|
17
|
+
fr.yml
|
18
|
+
...
|
19
|
+
```
|
20
|
+
|
21
|
+
Run the following command:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
yaml-validator config/locales
|
25
|
+
|
26
|
+
or
|
27
|
+
|
28
|
+
cd config/locales
|
29
|
+
yaml-validator
|
30
|
+
```
|
31
|
+
|
32
|
+
it will validate the files (in reference to en.yml) and show the following types of errors:
|
33
|
+
|
34
|
+
```
|
35
|
+
he.yml: parent_key.key1 doesn't exist in en.yml
|
36
|
+
fr.yml: found character that cannot start any token while scanning for the next token at line 19 column 14
|
37
|
+
nl.yml: parent_key.key1: missing variable 'var_with_typo' (available options var_without_type)
|
38
|
+
|
39
|
+
```
|
40
|
+
|
data/Rakefile
ADDED
data/bin/yaml-validator
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/yaml-validator'
|
4
|
+
|
5
|
+
def main
|
6
|
+
root_path = '.'
|
7
|
+
root_path = ARGV[0] if ARGV.length > 0
|
8
|
+
|
9
|
+
puts "Validating #{root_path}"
|
10
|
+
errors = YamlValidator.new(root_path).validate()
|
11
|
+
puts errors
|
12
|
+
puts "\nfound #{errors.length} errors"
|
13
|
+
end
|
14
|
+
|
15
|
+
main()
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'yaml-validator/version'
|
3
|
+
|
4
|
+
class YamlValidator
|
5
|
+
|
6
|
+
def initialize(root_path)
|
7
|
+
@root_path = root_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def en_with_vars
|
11
|
+
@en ||= YAML.load_file(File.join(@root_path, 'en.yml'))['en']
|
12
|
+
@en_with_vars ||= get_all_variables(@en)
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate()
|
16
|
+
yml_files = File.join(@root_path, '*.yml')
|
17
|
+
errors = []
|
18
|
+
Dir[yml_files].each do |filename|
|
19
|
+
errors.concat validate_yaml(filename)
|
20
|
+
end
|
21
|
+
errors
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate_yaml(filepath)
|
25
|
+
filename = File.basename(filepath)
|
26
|
+
|
27
|
+
begin
|
28
|
+
yaml_object = YAML.load_file(filepath)
|
29
|
+
rescue Psych::SyntaxError => e
|
30
|
+
return [e.message.sub(/^\([^)]+\)/, filename)]
|
31
|
+
end
|
32
|
+
yaml_object = yaml_object[yaml_object.keys[0]]
|
33
|
+
errors = validate_yaml_object('', yaml_object)
|
34
|
+
|
35
|
+
errors.map { |err| "#{filename}: #{err}" }
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate_yaml_object(full_key, yaml_object)
|
39
|
+
errors = []
|
40
|
+
yaml_object.each do |key, value|
|
41
|
+
full_subkey = (full_key.empty?) ? key : "#{full_key}.#{key}"
|
42
|
+
if value.is_a? String
|
43
|
+
errors.concat validate_item(full_subkey, value)
|
44
|
+
else
|
45
|
+
errors.concat validate_yaml_object(full_subkey, value)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
errors
|
49
|
+
end
|
50
|
+
|
51
|
+
def validate_item(full_key, value)
|
52
|
+
real_vars = get_key_en_vars(full_key)
|
53
|
+
if real_vars.nil?
|
54
|
+
return ["#{full_key} doesn't exist in en.yml"]
|
55
|
+
end
|
56
|
+
|
57
|
+
used_vars = identify_variables(value)
|
58
|
+
|
59
|
+
errors = []
|
60
|
+
used_vars.each do |var|
|
61
|
+
unless real_vars.include? var
|
62
|
+
errors << "#{full_key}: missing variable '#{var}' (available options: #{real_vars.join(', ')})"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
errors
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_key_en_vars(full_key)
|
69
|
+
position = en_with_vars
|
70
|
+
full_key.split('.').each do |key|
|
71
|
+
return nil if position.is_a? Array
|
72
|
+
return nil if position.nil?
|
73
|
+
position = position[key]
|
74
|
+
end
|
75
|
+
if position.is_a? Array
|
76
|
+
position
|
77
|
+
else
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_all_variables(yaml_object)
|
83
|
+
with_vars = {}
|
84
|
+
yaml_object.each do |key, value|
|
85
|
+
if value.is_a? String
|
86
|
+
with_vars[key] = identify_variables(value)
|
87
|
+
else
|
88
|
+
with_vars[key] = get_all_variables(value)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
with_vars
|
92
|
+
end
|
93
|
+
|
94
|
+
def identify_variables(string)
|
95
|
+
string.scan(/%{([^}]+)}/).map { |v| v[0] }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
key: %{var}
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative '../lib/yaml-validator'
|
4
|
+
|
5
|
+
describe YamlValidator do
|
6
|
+
|
7
|
+
describe "#validate" do
|
8
|
+
|
9
|
+
describe "wrong_variables scenario" do
|
10
|
+
it "returns two errors" do
|
11
|
+
validator = YamlValidator.new('spec/fixtures/wrong_variables')
|
12
|
+
errors = validator.validate()
|
13
|
+
errors.should == [
|
14
|
+
"he.yml: parent1.key1: missing variable 'name1' (available options: name, day_of_week)",
|
15
|
+
"he.yml: parent1.key1: missing variable 'day_of_week1' (available options: name, day_of_week)"
|
16
|
+
]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "inconsistent_types scenario" do
|
21
|
+
it "returns inconsistent type error" do
|
22
|
+
validator = YamlValidator.new('spec/fixtures/inconsistent_types')
|
23
|
+
errors = validator.validate()
|
24
|
+
errors.should == [
|
25
|
+
"he.yml: parent1.key1.subkey1 doesn't exist in en.yml",
|
26
|
+
"he.yml: parent2.key2 doesn't exist in en.yml",
|
27
|
+
"he.yml: key3 doesn't exist in en.yml",
|
28
|
+
"he.yml: parent3.key4 doesn't exist in en.yml"
|
29
|
+
]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "invalid yaml files" do
|
34
|
+
it "returns invalid yaml error" do
|
35
|
+
validator = YamlValidator.new('spec/fixtures/invalid_yml')
|
36
|
+
errors = validator.validate()
|
37
|
+
errors.should == [
|
38
|
+
"invalid.yml: found character that cannot start any token " +
|
39
|
+
"while scanning for the next token at line 1 column 6"
|
40
|
+
]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#validate_yaml" do
|
47
|
+
it "returns two errors" do
|
48
|
+
validator = YamlValidator.new('spec/fixtures/wrong_variables')
|
49
|
+
errors = validator.validate_yaml('spec/fixtures/wrong_variables/he.yml')
|
50
|
+
errors == [
|
51
|
+
"he.yml: parent1.key1: missing variable 'name1' (available options: name, day_of_week)",
|
52
|
+
"he.yml: parent1.key1: missing variable 'day_of_week1' (available options: name, day_of_week)"
|
53
|
+
]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
describe "#validate_item" do
|
59
|
+
describe "for 'parent1.key1' = 'hello %{name1}, %{day_of_week1}'" do
|
60
|
+
it "returns two errors" do
|
61
|
+
validator = YamlValidator.new('spec/fixtures/wrong_variables')
|
62
|
+
errors = validator.validate_item('parent1.key1', 'hello %{name1}, %{day_of_week1}')
|
63
|
+
errors.should == [
|
64
|
+
"parent1.key1: missing variable 'name1' (available options: name, day_of_week)",
|
65
|
+
"parent1.key1: missing variable 'day_of_week1' (available options: name, day_of_week)"
|
66
|
+
]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#get_key_en_vars" do
|
72
|
+
describe "for 'parent1'" do
|
73
|
+
it "returns nil" do
|
74
|
+
validator = YamlValidator.new('spec/fixtures/wrong_variables')
|
75
|
+
validator.get_key_en_vars('parent1').should be_nil
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "for 'parent1.key1'" do
|
80
|
+
it "returns ['name', 'day_of_week']" do
|
81
|
+
validator = YamlValidator.new('spec/fixtures/wrong_variables')
|
82
|
+
validator.get_key_en_vars('parent1.key1').should == ['name', 'day_of_week']
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "for 'parent1.nonexisting_key'" do
|
87
|
+
it "returns nil" do
|
88
|
+
validator = YamlValidator.new('spec/fixtures/wrong_variables')
|
89
|
+
validator.get_key_en_vars('parent1.nonexisting_key').should == nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
describe "for 'parent1.nonexisting_parent.key1'" do
|
93
|
+
it "returns nil" do
|
94
|
+
validator = YamlValidator.new('spec/fixtures/wrong_variables')
|
95
|
+
validator.get_key_en_vars('parent1.nonexisting_parent.key1').should == nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
describe "for 'parent1.key1.nonexisting_subkey'" do
|
99
|
+
it "returns nil" do
|
100
|
+
validator = YamlValidator.new('spec/fixtures/wrong_variables')
|
101
|
+
validator.get_key_en_vars('parent1.key1.nonexisting_subkey').should == nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "#get_all_variables" do
|
107
|
+
subject { YamlValidator.new(nil) }
|
108
|
+
describe "for { parent1: { key1: 'hello %{name}' } }" do
|
109
|
+
it "returns { parent1: { key1: ['name'] } }" do
|
110
|
+
input = { :parent1 => { :key1 => "hello %{name}" } }
|
111
|
+
subject.get_all_variables(input).should == { :parent1 => { :key1 => ['name'] } }
|
112
|
+
end
|
113
|
+
end
|
114
|
+
describe "for { parent1: { parent2: { key1: 'hello %{name}' } } }" do
|
115
|
+
it "returns { parent1: { parent2: { key1: ['name'] } } }" do
|
116
|
+
input = { :parent1 => { :parent2 => { :key1 => "hello %{name}" } } }
|
117
|
+
subject.get_all_variables(input).should ==
|
118
|
+
{ :parent1 => { :parent2 => { :key1 => ['name'] } } }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "#identify_variables" do
|
124
|
+
subject { YamlValidator.new(nil) }
|
125
|
+
describe "for 'Hello, hi'" do
|
126
|
+
it "returns []" do
|
127
|
+
subject.identify_variables('Hello, hi').should == []
|
128
|
+
end
|
129
|
+
end
|
130
|
+
describe "for 'Hello, %{name}, this is %{day_of_week}" do
|
131
|
+
it "returns ['name', 'day_of_week']" do
|
132
|
+
string = 'Hello, %{name}, this is %{day_of_week}'
|
133
|
+
subject.identify_variables(string).should == %w{name day_of_week}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'yaml-validator/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "yaml-validator"
|
8
|
+
gem.version = YamlValidator::VERSION
|
9
|
+
gem.authors = ["David Elentok"]
|
10
|
+
gem.email = ["3david@gmail.com"]
|
11
|
+
gem.description = %q{YAML locales validator}
|
12
|
+
gem.summary = %q{Validates .yml locale files for Ruby on Rails projects}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency('rake')
|
21
|
+
gem.add_dependency('rspec')
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yaml-validator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- David Elentok
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: YAML locales validator
|
47
|
+
email:
|
48
|
+
- 3david@gmail.com
|
49
|
+
executables:
|
50
|
+
- yaml-validator
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- .rspec
|
55
|
+
- Gemfile
|
56
|
+
- Gemfile.lock
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- bin/yaml-validator
|
60
|
+
- lib/yaml-validator.rb
|
61
|
+
- lib/yaml-validator/version.rb
|
62
|
+
- spec/fixtures/inconsistent_types/en.yml
|
63
|
+
- spec/fixtures/inconsistent_types/he.yml
|
64
|
+
- spec/fixtures/invalid_yml/invalid.yml
|
65
|
+
- spec/fixtures/wrong_variables/en.yml
|
66
|
+
- spec/fixtures/wrong_variables/he.yml
|
67
|
+
- spec/yaml-validator_spec.rb
|
68
|
+
- yaml-validator.gemspec
|
69
|
+
homepage: ''
|
70
|
+
licenses: []
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
hash: 1983922220360573853
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
hash: 1983922220360573853
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 1.8.24
|
96
|
+
signing_key:
|
97
|
+
specification_version: 3
|
98
|
+
summary: Validates .yml locale files for Ruby on Rails projects
|
99
|
+
test_files:
|
100
|
+
- spec/fixtures/inconsistent_types/en.yml
|
101
|
+
- spec/fixtures/inconsistent_types/he.yml
|
102
|
+
- spec/fixtures/invalid_yml/invalid.yml
|
103
|
+
- spec/fixtures/wrong_variables/en.yml
|
104
|
+
- spec/fixtures/wrong_variables/he.yml
|
105
|
+
- spec/yaml-validator_spec.rb
|