named_validations 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 451f3d677b38d83d61f4444559b06eadc0bec731
4
+ data.tar.gz: 112a67da0e1f00526f2b85b199c107f36811f688
5
+ SHA512:
6
+ metadata.gz: 60e77c7abced8e985d1b96f17b5181110cffd5562cb90c67da113fe6ffe07292ff55156831dc6a874b78efaf90bfac06459fda2fbaa01a292c883fb6972393af
7
+ data.tar.gz: 45e054fde95322cc25f7f92548309390b7d4b4cd3a008c0df053eb7f3814a63d55020392d361b7bf6e5252b1f7d052d24a15210751f7f534d7e636810cc9e560
data/.gitignore ADDED
@@ -0,0 +1,94 @@
1
+ # Created by https://www.gitignore.io/api/ruby,osx,vim,sublimetext
2
+
3
+ ### Ruby ###
4
+ *.gem
5
+ *.rbc
6
+ /.config
7
+ /coverage/
8
+ /InstalledFiles
9
+ /pkg/
10
+ /spec/reports/
11
+ /spec/examples.txt
12
+ /test/tmp/
13
+ /test/version_tmp/
14
+ /tmp/
15
+
16
+ # Used by dotenv library to load environment variables.
17
+ # .env
18
+
19
+ ## Specific to RubyMotion:
20
+ .dat*
21
+ .repl_history
22
+ build/
23
+ *.bridgesupport
24
+ build-iPhoneOS/
25
+ build-iPhoneSimulator/
26
+
27
+ ## Specific to RubyMotion (use of CocoaPods):
28
+ #
29
+ # We recommend against adding the Pods directory to your .gitignore. However
30
+ # you should judge for yourself, the pros and cons are mentioned at:
31
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
32
+ #
33
+ # vendor/Pods/
34
+
35
+ ## Documentation cache and generated files:
36
+ /.yardoc/
37
+ /_yardoc/
38
+ /doc/
39
+ /rdoc/
40
+
41
+ ## Environment normalization:
42
+ /.bundle/
43
+ /vendor/bundle
44
+ /lib/bundler/man/
45
+
46
+ # for a library or gem, you might want to ignore these files since the code is
47
+ # intended to run in multiple environments; otherwise, check them in:
48
+ Gemfile.lock
49
+ .ruby-version
50
+ .ruby-gemset
51
+
52
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
53
+ .rvmrc
54
+
55
+
56
+ ### OSX ###
57
+ *.DS_Store
58
+ .AppleDouble
59
+ .LSOverride
60
+
61
+ # Icon must end with two \r
62
+ Icon
63
+
64
+ # Thumbnails
65
+ ._*
66
+
67
+ # Files that might appear in the root of a volume
68
+ .DocumentRevisions-V100
69
+ .fseventsd
70
+ .Spotlight-V100
71
+ .TemporaryItems
72
+ .Trashes
73
+ .VolumeIcon.icns
74
+ .com.apple.timemachine.donotpresent
75
+
76
+ # Directories potentially created on remote AFP share
77
+ .AppleDB
78
+ .AppleDesktop
79
+ Network Trash Folder
80
+ Temporary Items
81
+ .apdisk
82
+
83
+
84
+ ### Vim ###
85
+ # swap
86
+ [._]*.s[a-w][a-z]
87
+ [._]s[a-w][a-z]
88
+ # session
89
+ Session.vim
90
+ # temporary
91
+ .netrwhist
92
+ *~
93
+ # auto-generated tag files
94
+ tags
data/.reek ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ SubclassedFromCoreClass:
3
+ exclude:
4
+ - NamedValidations
data/.rubocop.yml ADDED
@@ -0,0 +1,12 @@
1
+ AllCops:
2
+ Exclude:
3
+ - named_validations.gemspec
4
+ DisplayCopNames: true
5
+ TargetRubyVersion: 2.3
6
+
7
+ Metrics/ClassLength:
8
+ Exclude:
9
+ - test/*_test.rb
10
+
11
+ Style/SingleLineBlockParams:
12
+ Methods: []
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.5
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ ruby '~> 2.3.1'
3
+ source 'https://rubygems.org'
4
+ gemspec
5
+
6
+ gem 'test-unit', '~> 3.2'
7
+ gem 'rubocop'
8
+ gem 'reek'
9
+ gem 'simplecov'
10
+ gem 'yard'
11
+ gem 'pry'
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 akira yamada
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,168 @@
1
+ # NamedValidations
2
+
3
+ NamedValidations defines aliases for a set of validations for ActiveModel's `validates` method.
4
+
5
+ Example:
6
+
7
+ ```ruby
8
+ class CommonValidations < NamedValidations
9
+ define :required, :presence, true
10
+ define :short_text, :length, maximum: 100
11
+ define :long_text, :length, maximum: 5_000
12
+ define :formatted_text, :format,
13
+ with: /\A(?:[^:[:space:]]+:[^\n]*(\n\s+[^\n]*)*\n)*\z/,
14
+ allow_blank: true
15
+ define :formatted_long_text do |*_args|
16
+ long_text.formatted_long_text
17
+ end
18
+ end
19
+
20
+ class Article < ApplicationRecord
21
+ base = CommonValidations.new
22
+ validates :title, base.short_text.required
23
+ validates :content, base.long_text(minmum: 100)
24
+ validates :meta, base.formatted_long_text
25
+ end
26
+ ```
27
+
28
+ ## Installation
29
+
30
+ Add this line to your application's Gemfile:
31
+
32
+ ```ruby
33
+ gem 'named_validations'
34
+ ```
35
+
36
+ And then execute:
37
+
38
+ $ bundle
39
+
40
+ Or install it yourself as:
41
+
42
+ $ gem install named_validations
43
+
44
+ ## Usage
45
+
46
+ ### Simple alias (define-by-value)
47
+
48
+ ```ruby
49
+ define :required, :presence, true
50
+ ```
51
+
52
+ First argument is a name for the defining alias.
53
+ Second argument is a validation name,
54
+ and third argument is parameters for it.
55
+
56
+ The above code defines new alias `:required`
57
+ which is equal to `{ presence: true }`.
58
+
59
+ Validation name can be any of defined aliases including your aliases.
60
+ NamedValidations has pre-defined aliases such as:
61
+
62
+ * `:absence`
63
+ * `:acceptance`
64
+ * `:associated`
65
+ * `:confirmation`
66
+ * `:exclusion`
67
+ * `:format`
68
+ * `:inclusion`
69
+ * `:length`
70
+ * `:numericality`
71
+ * `:presence`
72
+ * `:size`
73
+ * `:uniqueness`
74
+
75
+ Parameters is usually Boolean or Hash.
76
+
77
+ ```ruby
78
+ define :short_text, :length, minimum: 5, maximum: 78
79
+ ```
80
+
81
+ It is equal to `{ length: { minimum: 5, maximum: 78 } }`.
82
+
83
+ ### Using alias
84
+
85
+ NamedValidations instance can receive a defined alias.
86
+
87
+ Simple alias and pre-defined aliases can take one or more arguments.
88
+ The argument is merged into return value of the alias.
89
+
90
+ ```ruby
91
+ class Sample < NamedValidations
92
+ define :required, :presence, true
93
+ end
94
+
95
+ base.required # represents: { presence: true }
96
+ base.required(false) # represents: { presence: false }
97
+ base.required(on: :create, ...) # represents: { presence: { on: :create, ... } }
98
+
99
+ base.required(false, { on: :create, foo: :bar }, { on: :update })
100
+ # represents: { presence: { on: :update, foo: :bar } }
101
+ ```
102
+
103
+ Alias returns new NamedValidations instance.
104
+
105
+ ```ruby
106
+ base = Sample.new # => #<Sample:0x3fe051053ec8>
107
+ base.required # => #<Sample:0x3fe0510132ec>
108
+ ```
109
+
110
+ So you can chain aliases.
111
+
112
+ ```ruby
113
+ base.length(maximum: 78).format(with: /@/)
114
+ # represents: { length: { maximum: 78}, format: { with: /@/ } }
115
+
116
+ vals = base.length(maximum: 78).length(minimum: 5)
117
+ # represents: { length: { maximum: 78, minimum: 5 } }
118
+
119
+ vals.length(maximum: 1_000)
120
+ # represents: { length: { maximum: 1_000, minimum: 5 } }
121
+ ```
122
+
123
+ ### Complex alias (define-by-block)
124
+
125
+ You can define more complex alias by using block.
126
+
127
+ ```ruby
128
+ define :long_format_text do |arg = true, *args|
129
+ length(maximum: 1_000)
130
+ .format({ with: /@/ }, *args)
131
+ .presence(arg)
132
+ end
133
+
134
+ define :clear do |*opts|
135
+ Sample.new
136
+ end
137
+ ```
138
+
139
+ The block should return a new NamedValidations instance.
140
+
141
+ Defined aliases can take some arguments
142
+ according to the block arguments.
143
+
144
+ ### Defaults options
145
+
146
+ NamedValidations has special alias `:defaults`.
147
+ It applies default options for validations.
148
+
149
+ ```ruby
150
+ validates :title, length(...).format(...).defaults(if: -> { ... })
151
+ # same as:
152
+ # validates :title, length: { ... }, format: { ... }, if: -> { ... }
153
+ ```
154
+
155
+ ## Development
156
+
157
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
158
+
159
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
160
+
161
+ ## Contributing
162
+
163
+ Bug reports and pull requests are welcome on GitHub at https://github.com/arika/named\_validations.
164
+
165
+
166
+ ## License
167
+
168
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ require 'bundler/gem_tasks'
3
+ require 'rake/testtask'
4
+ require 'rubocop/rake_task'
5
+ require 'reek/rake/task'
6
+ require 'yard'
7
+ require 'yard/rake/yardoc_task'
8
+
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'test'
11
+ t.libs << 'lib'
12
+ t.test_files = FileList['test/**/*_test.rb']
13
+ end
14
+
15
+ RuboCop::RakeTask.new
16
+ Reek::Rake::Task.new
17
+ YARD::Rake::YardocTask.new
18
+
19
+ task default: %i(test rubocop reek)
data/bin/console ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'named_validations'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ require 'pry'
11
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+ require 'named_validations/version'
3
+
4
+ # Naming to ActiveModel/ActiveRecord validations
5
+ class NamedValidations < Hash
6
+ # Reserved names
7
+ RESERVED = %i(
8
+ extractable_options?
9
+ class inspect
10
+ merge deep_merge
11
+ deep_merge_internal
12
+ ).freeze
13
+ private_constant :RESERVED
14
+
15
+ class << self
16
+ # @overload define(name, validation, params)
17
+ # Defines a new simple alias (define-by-value)
18
+ # @param name [Symbol] new alias name
19
+ # @param validation [Symbol] validation name or defined alias name
20
+ # @param params [Object] parameters or arguments for validation
21
+ # @overload define(name, block)
22
+ # Defines a new alias by block (define-by-block)
23
+ # @param name [Symbol] new alias name
24
+ # @param block [Proc] body of alias
25
+ def define(name, *spec, &block)
26
+ raise ArgumentError, "reserved name #{name}" if RESERVED.include?(name)
27
+ return define_by_block(name, block) if spec.empty?
28
+
29
+ validation, params, = spec
30
+ define_by_value(name, validation, params)
31
+ end
32
+
33
+ # Returns list of defined alias names
34
+ # @return [Array<Symbol>]
35
+ def aliases
36
+ @aliases ||= []
37
+ end
38
+
39
+ private
40
+
41
+ def inherited(sub_class)
42
+ # Merge defined alias names list
43
+ aliases.each { |name| sub_class.aliases << name }
44
+ end
45
+
46
+ def define_by_block(name, block)
47
+ define_method(name, block)
48
+ aliases << name
49
+ name
50
+ end
51
+
52
+ def define_by_value(name, validation, params)
53
+ raise ArgumentError,
54
+ "unknown alias #{name}" unless aliases.include?(validation)
55
+
56
+ block = -> (*opts) { public_send(validation, params, *opts) }
57
+ define_by_block(name, block)
58
+ end
59
+
60
+ # Defines aliases for ActiveModel/ActiveRecord validations
61
+ # @!macro attach define_for
62
+ # Apply `$1` to `self` and return a new object
63
+ # @!method $1(arg, *opts)
64
+ # @return [NamedValidations]
65
+ def define_for(name)
66
+ define(name) { |arg, *opts| deep_merge(name, arg, *opts) }
67
+ end
68
+ end
69
+
70
+ define_for :absence
71
+ define_for :confirmation
72
+ define_for :format
73
+ define_for :inclusion
74
+ define_for :numericality
75
+ define_for :acceptance
76
+ define_for :exclusion
77
+ define_for :length
78
+ define_for :presence
79
+ define_for :uniqueness
80
+ define_for :associated
81
+ define_for :size
82
+
83
+ # Defines an alias for default options
84
+ define(:defaults) { |default_opts| merge(default_opts) }
85
+
86
+ # Returns true
87
+ #
88
+ # @note This method is needed for ActiveSupport `Hash#extract_options!`.
89
+ def extractable_options?
90
+ true
91
+ end
92
+
93
+ # Inspects self
94
+ def inspect
95
+ klass = self.class
96
+ class_name = klass.name ||
97
+ Kernel.format('(Anonymous:0x%x)', klass.object_id)
98
+ Kernel.format('#<%s:0x%x>', class_name, object_id)
99
+ end
100
+
101
+ protected
102
+
103
+ # Returns a new object containing the given validations
104
+ # and the current validations.
105
+ def deep_merge(validation, params, *opts)
106
+ new_obj = deep_merge_internal(validation, params)
107
+ opts.inject(new_obj) { |obj, opt| obj.deep_merge(validation, opt) }
108
+ end
109
+
110
+ private
111
+
112
+ def deep_merge_internal(validation, params)
113
+ cur_params = self[validation]
114
+ if !params.is_a?(Hash) || !cur_params.is_a?(Hash)
115
+ new_params = params
116
+ else
117
+ new_params = params.inject(cur_params) do |hash, (key, value)|
118
+ hash.merge(key => value)
119
+ end
120
+ end
121
+
122
+ merge(validation => new_params)
123
+ end
124
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ class NamedValidations < Hash
3
+ VERSION = '0.1.0'
4
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'named_validations/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'named_validations'
8
+ spec.version = NamedValidations::VERSION
9
+ spec.authors = ['akira yamada']
10
+ spec.email = ['akira@arika.org']
11
+
12
+ spec.summary = 'Naming to ActiveModel/ActiveRecord validations'
13
+ spec.description = 'named_validations names to arguments of active_model\'s validates method.'
14
+ spec.homepage = 'https://github.com/arika/named_validations'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.12'
23
+ spec.add_development_dependency 'rake', '~> 11.0'
24
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: named_validations
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - akira yamada
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-06-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '11.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '11.0'
41
+ description: named_validations names to arguments of active_model's validates method.
42
+ email:
43
+ - akira@arika.org
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - ".reek"
50
+ - ".rubocop.yml"
51
+ - ".travis.yml"
52
+ - Gemfile
53
+ - LICENSE.txt
54
+ - README.md
55
+ - Rakefile
56
+ - bin/console
57
+ - bin/setup
58
+ - lib/named_validations.rb
59
+ - lib/named_validations/version.rb
60
+ - named_validations.gemspec
61
+ homepage: https://github.com/arika/named_validations
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.5.1
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: Naming to ActiveModel/ActiveRecord validations
85
+ test_files: []
86
+ has_rdoc: