yaml-validator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --format doc
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
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
@@ -0,0 +1,4 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
@@ -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,3 @@
1
+ class YamlValidator
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,6 @@
1
+ en:
2
+ parent1:
3
+ key1: "Hello, %{name}, this is %{day_of_week}"
4
+ parent2:
5
+ key2:
6
+ subkey: 'bla bla'
@@ -0,0 +1,9 @@
1
+ he:
2
+ parent1:
3
+ key1:
4
+ subkey1: 'bla bla'
5
+ parent2:
6
+ key2: 'bla bla bla'
7
+ key3: 'bla1'
8
+ parent3:
9
+ key4: 'bla2'
@@ -0,0 +1 @@
1
+ key: %{var}
@@ -0,0 +1,3 @@
1
+ en:
2
+ parent1:
3
+ key1: "Hello, %{name}, this is %{day_of_week}"
@@ -0,0 +1,3 @@
1
+ he:
2
+ parent1:
3
+ key1: "Hello, %{name1}, this is %{day_of_week1}"
@@ -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