activerecord_json_validator 0.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22cf2432dfb4427ba383de56c603a6ab9a02ff74
4
- data.tar.gz: eb005d90645dcf4e6471d7bd784523d67146418d
3
+ metadata.gz: b48b4031de5f8c6acbebdf18140fcedba69ed87c
4
+ data.tar.gz: c378d6029f74ab611000db2ade4b785beec0f031
5
5
  SHA512:
6
- metadata.gz: 637ba361b8d482dbe0edea5e27a96a815af724b9cfa5a2cdf7504d0f7f64a26b0e82e3228ad34a044b3e5ea64129f36556889dfa23a6a8d01d22830feb706705
7
- data.tar.gz: 910b92a51b66a283b60a15d79854ca58c05104c786de9d0a7a578e21c9ef782c5a5e0bba46ef88df12aed68d5a80f6ec03e71156e4610751cd16dee254a05461
6
+ metadata.gz: 587e07e4a9fbb7dabc6e82dc880dd7069ee1eaf89b32f9523512d0d6e5ec5724e383f1e0301b2ef76c820b09a2370c59e7ed0e62d5fd4a919a2279b7ffda9e60
7
+ data.tar.gz: 6d8edfea72e360af096bf8abc94c8b9b56db6e4028f712e06488aa179a1dec59df06cf386bfe7bb986a779bba8ae3eabe67c552182c3cb59d0fab52046e59c9b
data/.rubocop.yml ADDED
@@ -0,0 +1,62 @@
1
+ AllCops:
2
+ Exclude:
3
+ - activerecord_json_validator.gemspec
4
+
5
+ Documentation:
6
+ Enabled: false
7
+
8
+ Encoding:
9
+ Enabled: false
10
+
11
+ LineLength:
12
+ Max: 200
13
+
14
+ AccessModifierIndentation:
15
+ EnforcedStyle: outdent
16
+
17
+ IfUnlessModifier:
18
+ Enabled: false
19
+
20
+ CaseIndentation:
21
+ IndentWhenRelativeTo: case
22
+ IndentOneStep: true
23
+
24
+ MethodLength:
25
+ CountComments: false
26
+ Max: 20
27
+
28
+ SignalException:
29
+ Enabled: false
30
+
31
+ ColonMethodCall:
32
+ Enabled: false
33
+
34
+ AsciiComments:
35
+ Enabled: false
36
+
37
+ RegexpLiteral:
38
+ Enabled: false
39
+
40
+ AssignmentInCondition:
41
+ Enabled: false
42
+
43
+ ParameterLists:
44
+ CountKeywordArgs: false
45
+
46
+ SingleLineBlockParams:
47
+ Methods:
48
+ - reduce:
49
+ - memo
50
+ - item
51
+
52
+ Metrics/AbcSize:
53
+ Enabled: false
54
+
55
+ Style/CollectionMethods:
56
+ Enabled: true
57
+
58
+ Style/SymbolArray:
59
+ Enabled: true
60
+
61
+ Style/ExtraSpacing:
62
+ Enabled: true
data/.travis.yml CHANGED
@@ -18,7 +18,9 @@ before_script:
18
18
  - mysql -e 'create database activerecord_json_validator_test;'
19
19
  - psql -c 'create database activerecord_json_validator_test;' -U postgres
20
20
 
21
- script: "echo 'DO IT' && bundle exec rake spec"
21
+ script:
22
+ - 'echo "Checking code style" && bundle exec phare'
23
+ - 'echo "Running tests" && bundle exec rake spec'
22
24
 
23
25
  addons:
24
26
  postgresql: 9.3
data/README.md CHANGED
@@ -56,6 +56,86 @@ user.valid? # => false
56
56
  user.profile_invalid_json # => '{invalid JSON":}'
57
57
  ```
58
58
 
59
+ #### Options
60
+
61
+ | Option | Description
62
+ |------------|-----------------------------------------------------
63
+ | `:schema` | The JSON schema to validate the data against (see **JSON schema option** section)
64
+ | `:message` | The ActiveRecord message added to the record errors (default: `:invalid_json`)
65
+
66
+ ##### JSON schema option
67
+
68
+ You can specify four kinds of value for the `:schema` option.
69
+
70
+ ###### A path to a file containing a JSON schema
71
+
72
+ ```ruby
73
+ class User < ActiveRecord::Base
74
+ # Constants
75
+ PROFILE_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json_schema').to_s
76
+
77
+ # Validations
78
+ validates :profile, presence: true, json: { schema: PROFILE_JSON_SCHEMA }
79
+ end
80
+ ```
81
+
82
+ ###### A Ruby `Hash` representing a JSON schema
83
+
84
+ ```ruby
85
+ class User < ActiveRecord::Base
86
+ # Constants
87
+ PROFILE_JSON_SCHEMA = {
88
+ type: 'object',
89
+ :'$schema' => 'http://json-schema.org/draft-03/schema',
90
+ properties: {
91
+ city: { type: 'string', required: false },
92
+ country: { type: 'string', required: true }
93
+ }
94
+ }
95
+
96
+ # Validations
97
+ validates :profile, presence: true, json: { schema: PROFILE_JSON_SCHEMA }
98
+ end
99
+ ```
100
+
101
+ ###### A plain JSON schema as a Ruby `String`
102
+
103
+ ```ruby
104
+ class User < ActiveRecord::Base
105
+ # Constants
106
+ PROFILE_JSON_SCHEMA = '{
107
+ "type": "object",
108
+ "$schema": "http://json-schema.org/draft-03/schema",
109
+ "properties": {
110
+ "city": { "type": "string", "required": false },
111
+ "country": { "type": "string", "required": true }
112
+ }
113
+ }'
114
+
115
+ # Validations
116
+ validates :profile, presence: true, json: { schema: PROFILE_JSON_SCHEMA }
117
+ end
118
+ ```
119
+
120
+ ###### A lambda that will get evaluated in the context of the validated record
121
+
122
+ The lambda must return a valid value for the `:schema` option (file path, JSON `String` or Ruby `Hash`).
123
+
124
+ ```ruby
125
+ class User < ActiveRecord::Base
126
+ # Constants
127
+ PROFILE_REGULAR_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json_schema').to_s
128
+ PROFILE_ADMIN_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile_admin.json_schema').to_s
129
+
130
+ # Validations
131
+ validates :profile, presence: true, json: { schema: lambda { dynamic_profile_schema } }
132
+
133
+ def dynamic_profile_schema
134
+ admin? ? PROFILE_ADMIN_JSON_SCHEMA : PROFILE_REGULAR_JSON_SCHEMA
135
+ end
136
+ end
137
+ ```
138
+
59
139
  ## License
60
140
 
61
141
  `ActiveRecord::JSONValidator` is © 2013-2015 [Mirego](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/activerecord_json_validator/blob/master/LICENSE.md) file.
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ end
12
12
 
13
13
  desc 'Start an IRB session with the gem'
14
14
  task :console do
15
- $:.unshift File.expand_path('..', __FILE__)
15
+ $LOAD_PATH.unshift File.expand_path('..', __FILE__)
16
16
  require 'activerecord_json_validator'
17
17
  require 'irb'
18
18
 
@@ -24,6 +24,8 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency 'pg'
25
25
  spec.add_development_dependency 'mysql2'
26
26
  spec.add_development_dependency 'activesupport', '>= 4.1.0', '< 5'
27
+ spec.add_development_dependency 'phare'
28
+ spec.add_development_dependency 'rubocop', '~> 0.28'
27
29
 
28
30
  spec.add_dependency 'json-schema', '~> 2.5'
29
31
  spec.add_dependency 'activerecord', '>= 4.1.0', '< 5'
@@ -28,11 +28,15 @@ class JsonValidator < ActiveModel::EachValidator
28
28
  json_value = ''
29
29
  end
30
30
 
31
- errors = ::JSON::Validator.fully_validate(options.fetch(:schema), json_value)
31
+ # Validate value with JSON::Validator
32
+ schema = fetch_schema_for_record(record)
33
+ errors = ::JSON::Validator.fully_validate(schema, json_value)
32
34
 
33
- if errors.any? || record.send(:"#{attribute}_invalid_json").present?
34
- record.errors.add(attribute, options.fetch(:message), value: value)
35
- end
35
+ # Everything is good if we don’t have any errors and we got valid JSON value
36
+ return true if errors.empty? && record.send(:"#{attribute}_invalid_json").blank?
37
+
38
+ # Add error message to the attribute
39
+ record.errors.add(attribute, options.fetch(:message), value: value)
36
40
  end
37
41
 
38
42
  protected
@@ -51,10 +55,17 @@ protected
51
55
  super(args)
52
56
  rescue MultiJson::LoadError, JSON::ParserError
53
57
  @#{attribute}_invalid_json = args
54
- super(invalid_json: true)
58
+ super({})
55
59
  end
56
60
  end
57
61
  RUBY
58
62
  end
59
63
  end
64
+
65
+ def fetch_schema_for_record(record)
66
+ schema = options.fetch(:schema)
67
+ return schema unless schema.is_a?(Proc)
68
+
69
+ record.instance_exec(&schema)
70
+ end
60
71
  end
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module JSONValidator
3
- VERSION = '0.3'
3
+ VERSION = '0.4'
4
4
  end
5
5
  end
@@ -9,23 +9,36 @@ describe JsonValidator do
9
9
  end
10
10
  end
11
11
 
12
+ json_schema = schema
12
13
  spawn_model :User do
13
- schema = {
14
- type: 'object',
15
- :'$schema' => 'http://json-schema.org/draft-03/schema',
16
- properties: {
17
- city: { type: 'string', required: false },
18
- country: { type: 'string', required: true }
19
- }
20
- }
21
-
22
14
  serialize :profile, JSON
23
15
  validates :name, presence: true
24
- validates :profile, presence: true, json: { schema: schema }
16
+ validates :profile, presence: true, json: { schema: json_schema }
17
+
18
+ def dynamic_json_schema
19
+ {
20
+ type: 'object',
21
+ :'$schema' => 'http://json-schema.org/draft-03/schema',
22
+ properties: {
23
+ foo: { type: 'string', required: false },
24
+ bar: { type: 'string', required: true }
25
+ }
26
+ }
27
+ end
25
28
  end
26
29
  end
27
30
 
28
31
  let(:user) { User.create(attributes) }
32
+ let(:schema) do
33
+ {
34
+ type: 'object',
35
+ :'$schema' => 'http://json-schema.org/draft-03/schema',
36
+ properties: {
37
+ city: { type: 'string', required: false },
38
+ country: { type: 'string', required: true }
39
+ }
40
+ }
41
+ end
29
42
 
30
43
  context 'with blank JSON value' do
31
44
  let(:attributes) { { name: 'Samuel Garneau', profile: {} } }
@@ -61,7 +74,23 @@ describe JsonValidator do
61
74
 
62
75
  specify do
63
76
  expect(user).to_not be_valid
77
+ expect(user.profile).to eql({})
64
78
  expect(user.profile_invalid_json).to eql('foo:}bar')
65
79
  end
66
80
  end
81
+
82
+ context 'with lambda schema option' do
83
+ # The dynamic schema makes `country` and `city` keys mandatory
84
+ let(:schema) { -> { dynamic_json_schema } }
85
+
86
+ context 'with valid JSON value' do
87
+ let(:attributes) { { name: 'Samuel Garneau', profile: { foo: 'bar', bar: 'foo' } } }
88
+ it { expect(user).to be_valid }
89
+ end
90
+
91
+ context 'with invalid JSON value' do
92
+ let(:attributes) { { name: 'Samuel Garneau', profile: {} } }
93
+ it { expect(user).not_to be_valid }
94
+ end
95
+ end
67
96
  end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,4 @@
1
- $:.unshift File.expand_path('../lib', __FILE__)
1
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
2
 
3
3
  require 'active_support/all'
4
4
  require 'rspec'
@@ -5,7 +5,7 @@ module DatabaseMacros
5
5
  klass = Class.new(ActiveRecord::Migration)
6
6
 
7
7
  # Create a new `up` that executes the argument
8
- klass.send(:define_method, :up) { self.instance_exec(&block) }
8
+ klass.send(:define_method, :up) { instance_exec(&block) }
9
9
 
10
10
  # Create a new instance of it and execute its `up` method
11
11
  klass.new.up
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord_json_validator
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.3'
4
+ version: '0.4'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rémi Prévost
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-16 00:00:00.000000000 Z
11
+ date: 2015-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,6 +100,34 @@ dependencies:
100
100
  - - "<"
101
101
  - !ruby/object:Gem::Version
102
102
  version: '5'
103
+ - !ruby/object:Gem::Dependency
104
+ name: phare
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rubocop
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '0.28'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '0.28'
103
131
  - !ruby/object:Gem::Dependency
104
132
  name: json-schema
105
133
  requirement: !ruby/object:Gem::Requirement
@@ -158,6 +186,7 @@ extra_rdoc_files: []
158
186
  files:
159
187
  - ".gitignore"
160
188
  - ".rspec"
189
+ - ".rubocop.yml"
161
190
  - ".travis.yml"
162
191
  - Gemfile
163
192
  - LICENSE.md