checkability 0.7.0 → 1.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d691bd54ab262dd07d0bdf1120d632a71003cfdc730002275d10333e21045526
4
- data.tar.gz: 104e1558d7867413f25e838d3db9aaf54d2a7f96b412dd1121149e9528c9f95d
3
+ metadata.gz: f427c18e28549b00de27a9b29d5c3278be27a07f76b5efeb3c88bd07c9fa8004
4
+ data.tar.gz: 68c2e5ca988d593452a15b07c2b0a9f6155cf4a170434c40509c2e8f570a1cff
5
5
  SHA512:
6
- metadata.gz: 42816cf5985cfcc1d0f680496f0fdde3fd3263f87a4b12010f9d3f33694481703c8ed3785531914cfd5143982001c6fbe2977a52de789d7c559720048d3657ec
7
- data.tar.gz: 00e84b4caa4c5fae3eea6ae4e7e1fb0c3550e29948c81df7a85aaf4ea8ae98bf1083e3559b1583d28243faecdd477ebdbb8b7eab33318cd6571f15b5a08b52a0
6
+ metadata.gz: 6f86d27e1c09d25597de9a6f82701aba4ebfe77c29c469857c1cb2b07d492e87485a9f234c957083220df84f03d66d991b1e700a7aa4121782e567a8be9a3cb2
7
+ data.tar.gz: d52836824181062c8e294b56e27d3b6d486b5860d6f13be64d2fe6cefd6c9e98f22d3980a1d35d5ebde74374f3df3c89a4be8bf1b2feb7be4f69ff750c23713c
data/README.md CHANGED
@@ -12,12 +12,12 @@ How to use my plugin.
12
12
  inside of any rails model do
13
13
  ```ruby
14
14
  class SomeModel
15
- acts_as_checkable strategy: proc { |a, b, c| a && (b || c) },
16
- checkers: uk_postcode_checkers
15
+ extend UKPostcodeCheckersConf
16
+ acts_as_checkable uk_postcode_checkers_conf
17
17
  end
18
18
  ```
19
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
20
+ https://github.com/azazelo/postcode_checker/blob/master/app/models/concerns/u_k_postcode_checkers_conf.rb
21
21
  then in your controller:
22
22
  ```ruby
23
23
  class ChecksController < ApplicationController
@@ -30,7 +30,7 @@ class ChecksController < ApplicationController
30
30
  message, alert_class =
31
31
  if @check.valid?
32
32
  @check.perform_check
33
- [@check.messages.join('<br/>'), _alert_class(@check.allowed)]
33
+ [@check.ch_messages.join('<br/>'), _alert_class(@check.ch_allowed)]
34
34
  else
35
35
  [@check.errors.full_messages.join('<br/>'), _alert_class(false)]
36
36
  end
data/lib/checkability.rb CHANGED
@@ -9,7 +9,6 @@ require_relative 'checkability/external_api_checker'
9
9
  require_relative 'checkability/external_api_connector'
10
10
  require_relative 'checkability/validator'
11
11
  require_relative 'checkability/acts_as_checkable'
12
- require_relative 'checkability/checker'
13
- require_relative 'checkability/abstract_checker'
12
+ require_relative 'checkability/base_checker'
14
13
 
15
14
  ActiveRecord::Base.include Checkability::ActsAsCheckable
@@ -17,19 +17,23 @@ module Checkability
17
17
  "Hash expected, got #{options.class.name}"
18
18
  end
19
19
 
20
- class_attribute :checkable_conf
20
+ class_attribute :ch_conf
21
21
 
22
- self.checkable_conf = options
22
+ self.ch_conf = options
23
23
  end
24
24
  end
25
25
 
26
- attr_accessor :allowed, :messages
26
+ attr_accessor :ch_allowed, :ch_messages
27
+
28
+ def initialize(params)
29
+ @ch_messages = []
30
+ @ch_allowed = nil
31
+ super(params)
32
+ end
27
33
 
28
34
  def perform_check
29
- self.allowed = nil
30
- self.messages = []
31
- self.allowed = Checkability::Checkable.new(self).check(checkable_conf)
32
- messages << "#{allowed}::'#{_value}' is #{_allowness}. "
35
+ Checkability::Checkable.new(self).check(ch_conf)
36
+ ch_messages << "#{ch_allowed}::'#{_value}' is #{_allowness}. "
33
37
  end
34
38
 
35
39
  private
@@ -39,13 +43,11 @@ module Checkability
39
43
  end
40
44
 
41
45
  def _attr_name
42
- checkable_conf[:attr_name] || :value
46
+ ch_conf[:attr_name] || :value
43
47
  end
44
48
 
45
- def _setup; end
46
-
47
49
  def _allowness
48
- allowed ? 'ALLOWED' : 'NOT allowed'
50
+ ch_allowed ? 'ALLOWED' : 'NOT allowed'
49
51
  end
50
52
  end
51
53
  end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'checker'
4
+
5
+ module Checkability
6
+ # @abstract
7
+ class BaseChecker < Checker
8
+ # @return [Handler]
9
+ attr_reader :stop_process_on_success, :stop_process_on_failure,
10
+ :success_message, :failure_message
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
+ @success_message = opts[:success_message] || 'Success.'
16
+ @failure_message = opts[:failure_message] || 'Failed.'
17
+
18
+ @next_handler = nil
19
+ post_initialize(opts) # implemented in subclass
20
+ end
21
+
22
+ # subclass should implement
23
+ def post_initialize(_opts)
24
+ nil
25
+ end
26
+
27
+ # @param [Handler] handler
28
+ #
29
+ # @return [Handler]
30
+ def next_handler(handler)
31
+ @next_handler = handler
32
+
33
+ handler
34
+ end
35
+
36
+ # @abstract
37
+ #
38
+ # @param [String] request
39
+ #
40
+ # @return [Boolean, nil]
41
+ def handle(check_obj)
42
+ res, mess = result_and_message(check_obj)
43
+ check_obj.ch_messages << mess
44
+ check_obj.ch_allowed = res
45
+
46
+ return if _stop_here?(res)
47
+
48
+ @next_handler&.handle(check_obj) if @next_handler
49
+ end
50
+
51
+ def result_and_message(check_obj = nil)
52
+ res = result(check_obj)
53
+
54
+ str = res ? success_message : failure_message
55
+ [res, message(res, str)]
56
+ # rescue StandardError => e
57
+ # [false, message(false, e)]
58
+ end
59
+
60
+ # subclass should implement
61
+ def result(_check_obj)
62
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
63
+ end
64
+
65
+ # subclass may override
66
+ def message(res, str)
67
+ "#{res}::#{str}"
68
+ end
69
+
70
+ private
71
+
72
+ def _stop_here?(res)
73
+ (res && stop_process_on_success) || (!res && stop_process_on_failure)
74
+ end
75
+ end
76
+ end
@@ -1,55 +1,57 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'forwardable'
4
+
3
5
  module Checkability
4
6
  # Implements check method to Iterate on chechers
5
7
  # Possible to implemet as Iterator in future
6
8
  #
7
9
  class Checkable
8
- attr_reader :checkable
10
+ attr_accessor :check_obj
11
+
12
+ extend Forwardable
13
+ def_delegators :@check_obj, :ch_messages, :ch_allowed
9
14
 
10
- def initialize(checkable)
11
- @checkable = checkable
12
- @checkable.messages = []
15
+ def initialize(check_obj)
16
+ @check_obj = check_obj
13
17
  end
14
18
 
15
19
  # 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
+ # validator .next_handler(storage)
21
+ # storage .next_handler(api_validator)
22
+ # api_validator.next_handler(api_finder)
23
+ # api_validator.next_handler(nil)
20
24
  #
21
25
  # validator.handle(request)
22
26
  #
23
- def check(opts)
24
- handler_confs = opts[:handler_confs]
25
- first_handler_name = opts[:first_handler]
27
+ def check(handler_confs)
28
+ first_handler_name = handler_confs.keys.first
26
29
  first_handler = _handlers(handler_confs)[first_handler_name]
27
30
 
28
- first_handler.handle(checkable)
29
- # rescue StandardError => e
30
- # checkable.messages << "false::#{e}: #{opts}."
31
- # false
31
+ first_handler.handle(check_obj)
32
+ rescue StandardError => e
33
+ check_obj.ch_messages << "false::#{e}: #{handler_confs}."
34
+ false
32
35
  end
33
36
 
34
37
  private
35
38
 
36
39
  def _handlers(handler_confs)
37
40
  handlers = _make_handlers(handler_confs)
41
+
38
42
  handlers.each do |handler_name, handler|
39
43
  next_handler_name = handler_confs[handler_name][:next_handler]
40
44
  handler.next_handler(handlers[next_handler_name]) if handlers[next_handler_name]
41
45
  end
42
46
  end
43
47
 
44
- def _make_handlers(handler_confs)
45
- handler_confs.transform_values do |handler_conf|
46
- _make_handler(handler_conf)
47
- end
48
+ def _make_handlers(confs)
49
+ confs.transform_values { |conf| _make_handler(conf) }
48
50
  end
49
51
 
50
52
  def _make_handler(conf)
51
- k = Checkability.const_get conf[:name].to_s.camelize
52
- k.new(conf)
53
+ Checkability.const_get(conf[:name].to_s.camelize)
54
+ .new(conf)
53
55
  end
54
56
  end
55
57
  end
@@ -3,6 +3,16 @@
3
3
  module Checkability
4
4
  # @abstract
5
5
  class Checker
6
+ # hook method to initialize concreet attributes
7
+ # @abstract
8
+ #
9
+ # @param [Hash]
10
+ #
11
+ # @return new object
12
+ def post_initialize(_opts)
13
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
14
+ end
15
+
6
16
  # @abstract
7
17
  #
8
18
  # @param [Handler] handler
@@ -23,17 +33,26 @@ module Checkability
23
33
  #
24
34
  # @param [String] request
25
35
  #
26
- # @return [Boolean, true|false]
27
- def check_value(_request)
36
+ # @return Array [ [Boolean, true|false], String, message] ]
37
+ def result_and_message(_object)
28
38
  raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
29
39
  end
30
40
 
31
41
  # @abstract
32
42
  #
33
- # @param [String] request
43
+ # @param [Checkable object] request
34
44
  #
35
45
  # @return [Boolean, true|false]
36
- def result_and_message(_object)
46
+ def result(_object)
47
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
48
+ end
49
+
50
+ # @abstract
51
+ #
52
+ # @params [Boolean], [String]
53
+ #
54
+ # @return [String]
55
+ def message(_res, _str)
37
56
  raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
38
57
  end
39
58
  end
@@ -1,43 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'faraday'
4
- require 'net/http'
5
- require 'net/https'
6
- require 'json'
7
-
8
- # frozen_string_literal: true
3
+ require 'forwardable'
9
4
 
10
5
  module Checkability
11
6
  # Checks if postcode exists in external API
12
7
  #
13
- class ExternalApiChecker < AbstractChecker
14
- attr_reader :path, :path_suffix, :check_method, :connection, :http_verb,
15
- :failure_message, :success_message
8
+ class ExternalApiChecker < BaseChecker
9
+ attr_reader :path, :path_suffix, :check_method, :connector, :http_verb
10
+
11
+ extend Forwardable
12
+ def_delegators :@connector, :connection
16
13
 
17
14
  def post_initialize(conf = {})
18
15
  @path = conf[:path]
19
16
  @http_verb = conf[:http_verb] || :get
20
17
  @path_suffix = conf[:path_suffix] || ''
21
18
  @check_method = conf[:check_method]
22
- @connection = Checkability::ExternalApiConnector.new(conf)
19
+ @connector = conf[:connector] ||
20
+ Checkability::ExternalApiConnector.new(conf[:path])
21
+ @resp = nil
23
22
  end
24
23
 
25
- private
24
+ def result(check_obj)
25
+ return false unless resp(check_obj).status == 200
26
26
 
27
- def _result(checkable)
28
- resp = connection
29
- .connect
30
- .send(http_verb, "#{checkable.value.delete(' ')}#{path_suffix}")
31
- return false unless resp.status == 200
27
+ check_method.call(_parsed(resp(check_obj)))
28
+ end
32
29
 
33
- check_method.call(_parsed(resp))
30
+ def resp(check_obj)
31
+ @resp ||= connection
32
+ .send(http_verb,
33
+ "#{check_obj.value.delete(' ')}#{path_suffix}")
34
+ # .get('SE17QD')
34
35
  end
35
36
 
36
- def message(str, res)
37
- str = "#{path}: #{str}"
38
- super(str, res)
37
+ def message(res, str = nil)
38
+ "#{res}::#{path}: #{str}"
39
39
  end
40
40
 
41
+ private
42
+
41
43
  def _parsed(resp)
42
44
  JSON.parse(resp.body)
43
45
  end
@@ -1,16 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'faraday'
4
+
3
5
  module Checkability
4
6
  # Create connection
5
7
  #
6
8
  class ExternalApiConnector
7
9
  attr_reader :path
8
10
 
9
- def initialize(conf)
10
- @path = conf[:path]
11
+ def initialize(path)
12
+ @path = path
11
13
  end
12
14
 
13
- def connect
15
+ def connection
14
16
  Faraday.new(url: path) do |faraday|
15
17
  faraday.headers['Content-Type'] = 'application/json'
16
18
  faraday.adapter Faraday.default_adapter
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'abstract_checker'
3
+ require_relative 'base_checker'
4
4
  module Checkability
5
5
  # Checks if postcode exists in Storage
6
6
  #
7
- class StorageChecker < AbstractChecker
7
+ class StorageChecker < BaseChecker
8
8
  attr_reader :storage_class, :attr_name
9
9
 
10
10
  def post_initialize(conf = {})
@@ -12,18 +12,17 @@ module Checkability
12
12
  @attr_name = conf[:attr_name] || :value
13
13
  end
14
14
 
15
- private
16
-
17
- def _result(checkable)
15
+ def result(checkable)
18
16
  value = _normalize_value(checkable.send(attr_name))
19
17
  storage_class.where(attr_name => value).present?
20
18
  end
21
19
 
22
- def message(str, res)
23
- str = "Allowed #{storage_class}s list: #{str}"
24
- super(str, res)
20
+ def message(res, str = nil)
21
+ "#{res}::Allowed #{storage_class}s list: #{str}"
25
22
  end
26
23
 
24
+ private
25
+
27
26
  def _normalize_value(value)
28
27
  value.delete(' ').upcase
29
28
  end
@@ -3,16 +3,14 @@
3
3
  module Checkability
4
4
  # Checks if postcode comply with regex
5
5
  #
6
- class Validator < AbstractChecker
6
+ class Validator < BaseChecker
7
7
  attr_reader :format
8
8
 
9
9
  def post_initialize(conf = {})
10
10
  @format = conf[:format]
11
11
  end
12
12
 
13
- private
14
-
15
- def _result(checkable)
13
+ def result(checkable)
16
14
  !(checkable.value.delete(' ') =~ format[:regex]).nil?
17
15
  end
18
16
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Checkability
4
- VERSION = '0.7.0'
4
+ VERSION = '1.0.0'
5
5
  end
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.7.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Eremeev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-03 00:00:00.000000000 Z
11
+ date: 2021-04-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Provide Checkers functionality.
14
14
  email:
@@ -23,8 +23,8 @@ files:
23
23
  - Rakefile
24
24
  - bin/checkability
25
25
  - lib/checkability.rb
26
- - lib/checkability/abstract_checker.rb
27
26
  - lib/checkability/acts_as_checkable.rb
27
+ - lib/checkability/base_checker.rb
28
28
  - lib/checkability/checkable.rb
29
29
  - lib/checkability/checker.rb
30
30
  - lib/checkability/external_api_checker.rb
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'checker'
4
-
5
- module Checkability
6
- # @abstract
7
- class AbstractChecker < Checker
8
- # @return [Handler]
9
- attr_reader :stop_process_on_failure, :stop_process_on_success
10
- attr_accessor :success_message, :failure_message, :handler
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
- @success_message = opts[:success_message] || 'Success.'
16
- @failure_message = opts[:failure_message] || 'Failed.'
17
-
18
- @next_handler = nil
19
- post_initialize(opts) # implemented in subclass
20
- end
21
-
22
- # @param [Handler] handler
23
- #
24
- # @return [Handler]
25
- def next_handler(handler)
26
- @handler = handler if handler
27
-
28
- handler
29
- end
30
-
31
- # @abstract
32
- #
33
- # @param [String] request
34
- #
35
- # @return [Boolean, nil]
36
- def handle(request)
37
- check = check_value(request) # imlemented in subclass
38
-
39
- return true if check && stop_process_on_success
40
-
41
- return false if !check && stop_process_on_failure
42
-
43
- handler&.handle(request)
44
- end
45
-
46
- def check_value(checkable)
47
- result, message = result_and_message(checkable)
48
- checkable.messages << message
49
- result
50
- end
51
-
52
- def result_and_message(checkable)
53
- result = _result(checkable)
54
- str = result ? success_message : failure_message
55
- [result, message(str, result)]
56
- rescue StandardError => e
57
- [false, message(e, false)]
58
- end
59
-
60
- def _result; end
61
-
62
- def message(str, res)
63
- "#{res}::#{str}"
64
- end
65
- end
66
- end