checkability 0.2.0 → 0.6.0

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
- SHA1:
3
- metadata.gz: 7c20a76958ba1f8025605a3ded3101c8a0e3eeb2
4
- data.tar.gz: 8b69ff85aea14d3726827e58954cc6efb8bdb502
2
+ SHA256:
3
+ metadata.gz: 0f584d475c0bf9395f3cbdb0d47a436b7f1a56ab93fb4d76095b58de9a0a4485
4
+ data.tar.gz: d9ff4ef5b3a877fd0a8efe830958df8e14d3ae0e221903fbb436623457c14e74
5
5
  SHA512:
6
- metadata.gz: 4fe465c7c77639f20865c2e37df153615298df3b6284587660b030ec0833bedc5bcfb14e59a39252988d1276721ece24fa88d8000291ae188a50ff1897ebb8eb
7
- data.tar.gz: 26494daaeae8b5497b2c2db96ee1c21ddfabf027b93a30e6b1dd91d06936f4dd4fdff616d2391cf5fa1620df07a7806fadb8b69899ee232619d95a67cfa0e8a0
6
+ metadata.gz: e7f9740350a632cea6131709f9e765f0c8e47981b564a8fb426103fe1c55688f7d27ce7190b11278e540807bd0e2dfeabe65d5d47d4e494b4865074db384447d
7
+ data.tar.gz: 4baa39ca9c3aaec3845e2d84a72f38caf74f662bab1b3f6ff453439763393db4865c7a3912b8c09f606d37a2b15860f779750f9d8cc0e8b19f102362310355d5
data/README.md CHANGED
@@ -9,8 +9,47 @@ with return of true|false
9
9
  ## Usage
10
10
  How to use my plugin.
11
11
 
12
- inside of any ruby class include Checkablilty
13
- next
12
+ inside of any rails model do
13
+ ```ruby
14
+ class SomeModel
15
+ acts_as_checkable strategy: proc { |a, b, c| a && (b || c) },
16
+ checkers: uk_postcode_checkers
17
+ end
18
+ ```
19
+ where `uk_postcode_checkers` is method which returns hash with configurations
20
+ https://github.com/azazelo/postcode_checker/blob/master/app/models/concerns/u_k_postcode_checkers.rb
21
+ then in your controller:
22
+ ```ruby
23
+ class ChecksController < ApplicationController
24
+ def checking
25
+ @check = Check.new
26
+ end
27
+
28
+ def perform
29
+ @check = Check.new(value: check_params[:string])
30
+ message, alert_class =
31
+ if @check.valid?
32
+ @check.perform_check
33
+ [@check.messages.join('<br/>'), _alert_class(@check.allowed)]
34
+ else
35
+ [@check.errors.full_messages.join('<br/>'), _alert_class(false)]
36
+ end
37
+ redirect_to checking_path, flash: { now: message, alert_class: alert_class }
38
+ end
39
+
40
+ private
41
+
42
+ def _alert_class(cond)
43
+ cond ? 'success' : 'danger'
44
+ end
45
+
46
+ def check_params
47
+ params.permit(:string)
48
+ end
49
+ end
50
+ ```
51
+ for more detailed example see application
52
+ in https://github.com/azazelo/postcode_checker
14
53
 
15
54
  ## Installation
16
55
  Add this line to your application's Gemfile:
@@ -34,3 +73,7 @@ Contribution directions go here.
34
73
 
35
74
  ## License
36
75
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
76
+
77
+ ## Future works
78
+
79
+ - [ ] Use ChainOfResponsibility pattern to simplify call of checkers
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/setup'
2
4
 
3
5
  require 'bundler/gem_tasks'
data/bin/checkability CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require_relative '../lib/checkability'
4
5
 
@@ -8,4 +9,3 @@ puts 'Gem provide acts_as_checkable addon to active record models'
8
9
  puts "Version: #{Checkability::VERSION}"
9
10
  puts ''
10
11
  puts '-----------------'
11
-
data/lib/checkability.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_record'
2
4
  require 'active_support'
3
5
  require_relative 'checkability/version'
@@ -7,5 +9,7 @@ require_relative 'checkability/external_api_checker'
7
9
  require_relative 'checkability/external_api_connector'
8
10
  require_relative 'checkability/validator'
9
11
  require_relative 'checkability/acts_as_checkable'
12
+ require_relative 'checkability/chain_of_resp/handler'
13
+ require_relative 'checkability/chain_of_resp/abstract_handler'
10
14
 
11
15
  ActiveRecord::Base.include Checkability::ActsAsCheckable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Checkability
2
4
  # Adding class and instance methods
3
5
  #
@@ -10,9 +12,7 @@ module Checkability
10
12
 
11
13
  class_methods do
12
14
  def acts_as_checkable(options = {})
13
- if !options.is_a?(Hash) && !options.empty?
14
- raise ArgumentError, "Hash expected, got #{options.class.name}"
15
- end
15
+ raise ArgumentError, "Hash expected, got #{options.class.name}" if !options.is_a?(Hash) && !options.empty?
16
16
 
17
17
  class_attribute :checkable_conf
18
18
 
@@ -21,23 +21,30 @@ module Checkability
21
21
  end
22
22
 
23
23
  attr_accessor :allowed, :messages
24
- def setup
25
- self.allowed = nil
26
- self.messages = []
24
+
25
+ def perform_check
26
+ _setup
27
+ self.allowed = Checkability::Checkable.new(self).check(checkable_conf)
28
+ messages << "#{allowed}::'#{_value}' is #{_allowness}. "
27
29
  end
28
30
 
29
- def perform
30
- setup
31
- self.allowed = _check
32
- messages << "#{self.class.name} '#{value}' is #{_allowness}. "
31
+ private
32
+
33
+ def _value
34
+ send(_attr_name)
33
35
  end
34
36
 
35
- def _allowness
36
- allowed ? 'ALLOWED' : 'NOT allowed'
37
+ def _attr_name
38
+ checkable_conf[:attr_name] || :value
37
39
  end
38
40
 
39
- def _check
40
- Checkability::Checkable.new(self).check(checkable_conf)
41
+ def _setup
42
+ self.allowed = nil
43
+ self.messages = []
44
+ end
45
+
46
+ def _allowness
47
+ allowed ? 'ALLOWED' : 'NOT allowed'
41
48
  end
42
49
  end
43
50
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'handler'
4
+
5
+ module ChainOfResp
6
+ # @abstract
7
+ class AbstractHandler < ChainOfResp::Handler
8
+ # @return [Handler]
9
+ attr_reader :stop_process_on_failure, :stop_process_on_success
10
+ attr_accessor :handler, :result
11
+
12
+ def initialize(opts = {})
13
+ @stop_process_on_failure = opts[:stop_process_on_failure] || false
14
+ @stop_process_on_success = opts[:stop_process_on_success] || false
15
+ @next_handler = nil
16
+ post_initialize(opts) # implemented in subclass
17
+ end
18
+
19
+ # @param [Handler] handler
20
+ #
21
+ # @return [Handler]
22
+ def next_handler(handler)
23
+ @handler = handler if handler
24
+
25
+ handler
26
+ end
27
+
28
+ # @abstract
29
+ #
30
+ # @param [String] request
31
+ #
32
+ # @return [Boolean, nil]
33
+ def handle(request)
34
+ check = check_value(request) # imlemented in subclass
35
+ return true if check && stop_process_on_success
36
+
37
+ return false if !check && stop_process_on_failure
38
+
39
+ handler&.handle(request)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChainOfResp
4
+ # @abstract
5
+ class Handler
6
+ # @abstract
7
+ #
8
+ # @param [Handler] handler
9
+ def next_handler=(_handler)
10
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
11
+ end
12
+
13
+ # @abstract
14
+ #
15
+ # @param [String] request
16
+ #
17
+ # @return [String, nil]
18
+ def handle(_request)
19
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
20
+ end
21
+
22
+ # @abstract
23
+ #
24
+ # @param [String] request
25
+ #
26
+ # @return [Boolean, true|false]
27
+ def check_value(_request)
28
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Checkability
2
4
  # Implements check method to Iterate on chechers
3
5
  # Possible to implemet as Iterator in future
@@ -7,21 +9,43 @@ module Checkability
7
9
 
8
10
  def initialize(checkable)
9
11
  @checkable = checkable
12
+ @checkable.messages = []
13
+ end
14
+
15
+ # As in result handlers should behave like this:
16
+ # validator .set_next(storage)
17
+ # storage .set_next(api_validator)
18
+ # api_validator.set_next(api_finder)
19
+ # api_validator.set_next(nil)
20
+ #
21
+ # validator.handle(request)
22
+ #
23
+ def check(opts = {})
24
+ require 'pry'; binding.pry
25
+ first_handler_name = opts[:first_handler]
26
+ _handlers(opts)[first_handler_name].handle(checkable)
27
+ rescue StandardError => e
28
+ checkable.messages << "false::#{e}: #{opts}."
29
+ false
30
+ end
31
+
32
+ private
33
+
34
+ def _handlers(opts)
35
+ handler_confs = opts[:handler_confs]
36
+ handlers = {}
37
+ handler_confs.each do |handler_name, handler_conf|
38
+ handlers[handler_name] = _make_handler(handler_name, handler_conf)
39
+ end
40
+ handlers.each do |handler_name, handler|
41
+ next_handler_name = handler_confs[handler_name][:next_handler]
42
+ handler.next_handler(handlers[next_handler_name])
43
+ end
10
44
  end
11
45
 
12
- # sentence is a proc
13
- # like { |a,b,c| a && ( b || c ) }
14
- # where a,b,c are checkers
15
- # and each should return true|false
16
- # checkers is an array of checker objects
17
- # e.g. [storage_checker, external_api_checker]
18
- def check(conf)
19
- conf[:algoritm].call(
20
- conf[:checkers].map do |checker_name, checker_conf|
21
- k = Checkability.const_get(checker_name.to_s.camelize)
22
- k.new(checker_conf).check_value(checkable)
23
- end
24
- )
46
+ def _make_handler(_name, conf)
47
+ k = Checkability.const_get conf[:name].to_s.camelize
48
+ k.new(conf)
25
49
  end
26
50
  end
27
51
  end
@@ -1,22 +1,34 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'faraday'
2
4
  require 'net/http'
3
5
  require 'net/https'
4
6
  require 'json'
5
7
 
8
+ # frozen_string_literal: true
9
+
10
+ require_relative 'chain_of_resp/abstract_handler'
6
11
  module Checkability
7
12
  # Checks if postcode exists in external API
8
13
  #
9
- class ExternalApiChecker
10
- attr_reader :path, :check_method, :connection
14
+ class ExternalApiChecker < ChainOfResp::AbstractHandler
15
+ attr_reader :path, :path_suffix, :check_method, :connection, :http_verb,
16
+ :failure_message, :success_message
11
17
 
12
- def initialize(conf = {})
18
+ def post_initialize(conf = {})
13
19
  @path = conf[:path]
20
+ @http_verb = conf[:http_verb] || :get
21
+ @path_suffix = conf[:path_suffix] || ''
14
22
  @check_method = conf[:check_method]
23
+ @failure_message = conf[:failure_message] || 'Failed.'
24
+ @success_message = conf[:success_message] || 'Success.'
15
25
  @connection = Checkability::ExternalApiConnector.new(conf)
16
26
  end
17
27
 
18
28
  def check_value(checkable)
19
- @resp = connection.connect.get(checkable.value.delete(' '))
29
+ @resp = connection
30
+ .connect
31
+ .send(http_verb, "#{checkable.value.delete(' ')}#{path_suffix}")
20
32
  result, message = _result_and_message
21
33
  checkable.messages << message
22
34
  result
@@ -24,8 +36,8 @@ module Checkability
24
36
 
25
37
  private
26
38
 
27
- def _message(str)
28
- "#{path}: #{str}"
39
+ def _message(str, res)
40
+ "#{res}::#{path}: #{str}"
29
41
  end
30
42
 
31
43
  def _parsed(resp)
@@ -33,13 +45,14 @@ module Checkability
33
45
  end
34
46
 
35
47
  def _result_and_message
36
- return [false, _message(@resp.status)] unless @resp.status == 200
48
+ return [false, _message(@resp.status, false)] unless @resp.status == 200
37
49
 
38
- return [true, _message('Found.')] if check_method.call(_parsed(@resp))
50
+ return [true, _message(success_message, true)] if check_method
51
+ .call(_parsed(@resp))
39
52
 
40
- [false, _message('Not found in allowed areas.')]
53
+ [false, _message(failure_message, false)]
41
54
  rescue StandardError => e
42
- [false, _message(e)]
55
+ [false, _message(e, false)]
43
56
  end
44
57
  end
45
58
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Checkability
2
4
  # Create connection
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Checkability
2
4
  class Railtie < ::Rails::Railtie
3
5
  end
@@ -1,17 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'chain_of_resp/abstract_handler'
1
4
  module Checkability
2
5
  # Checks if postcode exists in Storage
3
6
  #
4
- class StorageChecker
7
+ class StorageChecker < ChainOfResp::AbstractHandler
5
8
  attr_reader :storage_class
6
9
 
7
- def initialize(conf = {})
10
+ def post_initialize(conf = {})
8
11
  @storage_class = conf[:storage_class]
9
12
  end
10
13
 
11
14
  def check_value(checkable)
12
15
  value = checkable.value.upcase
13
16
  result = _present_in_storage(value)
14
- checkable.messages << (result ? _message('Found') : _message('Not found'))
17
+ checkable.messages << (
18
+ result ? _message('Found', result) : _message('Not found', result))
15
19
  result
16
20
  end
17
21
 
@@ -22,8 +26,8 @@ module Checkability
22
26
  .present?
23
27
  end
24
28
 
25
- def _message(str)
26
- "Allowed #{storage_class}s list: #{str}."
29
+ def _message(str, res)
30
+ "#{res}::Allowed #{storage_class}s list: #{str}."
27
31
  end
28
32
  end
29
33
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Checkability
2
4
  # Checks if postcode comply with regex
3
5
  #
4
- class Validator
6
+ class Validator < ChainOfResp::AbstractHandler
5
7
  attr_reader :format
6
8
 
7
- def initialize(conf = {})
9
+ def post_initialize(conf = {})
8
10
  @format = conf[:format]
9
11
  end
10
12
 
@@ -14,11 +16,13 @@ module Checkability
14
16
  result
15
17
  end
16
18
 
19
+ private
20
+
17
21
  def _result_and_message(checkable)
18
22
  if (checkable.value.delete(' ') =~ format[:regex]).nil?
19
- [false, "Value is not comply with format of #{format[:name]}."]
23
+ [false, "false::Value is NOT COMPLY with format of #{format[:name]}."]
20
24
  else
21
- [true, "Value comply with format of #{format[:name]}."]
25
+ [true, "true::Value is COMPLY with format of #{format[:name]}."]
22
26
  end
23
27
  end
24
28
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Checkability
2
- VERSION = '0.2.0'.freeze
4
+ VERSION = '0.6.0'
3
5
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # desc "Explaining what the task does"
2
3
  # task :checkability do
3
4
  # # Task goes here
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: checkability
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Eremeev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-30 00:00:00.000000000 Z
11
+ date: 2021-04-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Provide Checkers functionality.
14
14
  email:
@@ -24,6 +24,8 @@ files:
24
24
  - bin/checkability
25
25
  - lib/checkability.rb
26
26
  - lib/checkability/acts_as_checkable.rb
27
+ - lib/checkability/chain_of_resp/abstract_handler.rb
28
+ - lib/checkability/chain_of_resp/handler.rb
27
29
  - lib/checkability/checkable.rb
28
30
  - lib/checkability/external_api_checker.rb
29
31
  - lib/checkability/external_api_connector.rb
@@ -40,7 +42,7 @@ metadata:
40
42
  homepage_uri: https://github.com/azazelo/checkability
41
43
  source_code_uri: https://rubygems.org
42
44
  changelog_uri: https://rubygems.org
43
- post_install_message:
45
+ post_install_message:
44
46
  rdoc_options: []
45
47
  require_paths:
46
48
  - lib
@@ -48,16 +50,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
48
50
  requirements:
49
51
  - - ">="
50
52
  - !ruby/object:Gem::Version
51
- version: '0'
53
+ version: 2.6.2
52
54
  required_rubygems_version: !ruby/object:Gem::Requirement
53
55
  requirements:
54
56
  - - ">="
55
57
  - !ruby/object:Gem::Version
56
58
  version: '0'
57
59
  requirements: []
58
- rubyforge_project:
59
- rubygems_version: 2.4.6
60
- signing_key:
60
+ rubygems_version: 3.0.3
61
+ signing_key:
61
62
  specification_version: 4
62
63
  summary: Provide Checkers functionality.
63
64
  test_files: []