actionizer 0.7.4 → 0.8.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
  SHA1:
3
- metadata.gz: f6623871ec5ccf598b08a3b75723eb62ea51228b
4
- data.tar.gz: ebfa581c615814d6091f9774774457809f4b6690
3
+ metadata.gz: a63a9ba128ed80a4d5090ddb1934f44a5281387f
4
+ data.tar.gz: b8d54516906e1766cefebc20e31c4831f9b95dd0
5
5
  SHA512:
6
- metadata.gz: 9e68faae5f420695bc7b15f3adb04d9cf17d9e6ad0496457e6b88befff41eb23c4158c28892e906350519110591ab64f31197678882ff5476cacc9bcd7fc943a
7
- data.tar.gz: 42c6e70e2f872ada9122833a433fffba6b2e098504e15582da91e0de97d251e231d7e9a099649e3c5cdf1d581ec0df4627d439dff80604e96c029b162a9957a0
6
+ metadata.gz: 4aa44e386f9957c7f52177084fb9e60d0ba3b0fe572f5eef09f30be13e62732059489f8e4927319e0554d27ea2b4c4538bc618f5e0df0e26315dff1dcdeb2432
7
+ data.tar.gz: ea3037ed552d5d9ae3b5aeb3ce37cef181c9a9cc612b18386e3abf3d2790ece33a3eb31c449c322d61c1c401107e49ba346525341e4a7e13b33c94e2a754a3bf
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  Metrics/AbcSize:
2
- Max: 20
2
+ Max: 25
3
3
  Metrics/LineLength:
4
4
  Max: 120
5
5
  Metrics/MethodLength:
@@ -11,7 +11,11 @@ Style/EmptyLinesAroundBlockBody:
11
11
  Enabled: false
12
12
  Style/EmptyLinesAroundClassBody:
13
13
  Enabled: false
14
+ Style/FrozenStringLiteralComment:
15
+ Enabled: false
14
16
  Style/MutableConstant:
15
17
  Enabled: false
18
+ Style/NegatedIf:
19
+ Enabled: false
16
20
  Style/TrivialAccessors:
17
21
  Enabled: false
data/lib/actionizer.rb CHANGED
@@ -2,6 +2,7 @@ require 'ostruct'
2
2
  require 'actionizer/result'
3
3
  require 'actionizer/failure'
4
4
  require 'actionizer/version'
5
+ require 'actionizer/inputs'
5
6
 
6
7
  module Actionizer
7
8
  attr_reader :input, :output
@@ -15,6 +16,9 @@ module Actionizer
15
16
  instance = new(*args)
16
17
 
17
18
  if instance.respond_to?(method_name)
19
+ error = defined_inputs.check_for_param_error(method_name, *args)
20
+ raise ArgumentError, error if error
21
+
18
22
  instance.tap(&method_name).output
19
23
  else
20
24
  super
@@ -26,6 +30,32 @@ module Actionizer
26
30
  def respond_to_missing?(method_name, include_private = false)
27
31
  new.respond_to?(method_name, include_private)
28
32
  end
33
+
34
+ def defined_inputs
35
+ @defined_inputs ||= Actionizer::Inputs.new
36
+ end
37
+
38
+ def inputs_for(method)
39
+ raise ArgumentError, 'inputs_for requires a block' if !block_given?
40
+
41
+ defined_inputs.start(method)
42
+ yield
43
+ defined_inputs.end
44
+
45
+ raise 'You must define at least one optional or required param' if defined_inputs.no_params_declared?(method)
46
+ end
47
+
48
+ def optional(param)
49
+ raise 'You must call optional from inside an inputs_for block' if defined_inputs.outside_inputs_for_block?
50
+
51
+ defined_inputs.add(param: param, required: false)
52
+ end
53
+
54
+ def required(param)
55
+ raise 'You must call required from inside an inputs_for block' if defined_inputs.outside_inputs_for_block?
56
+
57
+ defined_inputs.add(param: param, required: true)
58
+ end
29
59
  end
30
60
 
31
61
  def initialize(initial_input = {})
@@ -43,23 +73,20 @@ module Actionizer
43
73
 
44
74
  # Allows you to call *_or_fail
45
75
  def method_missing(method_name, *args, &block)
46
- return super unless method_name.to_s.end_with?('_or_fail')
76
+ return super if !method_name.to_s.end_with?('_or_fail')
47
77
 
48
78
  action_class, *params = args
49
79
  underlying_method = method_name.to_s.chomp('_or_fail')
50
80
 
51
- unless action_class.respond_to?(underlying_method)
81
+ if !action_class.respond_to?(underlying_method)
52
82
  raise ArgumentError, "#{action_class.name} must define ##{underlying_method}"
53
83
  end
54
84
 
55
85
  result = action_class.send(underlying_method, *params)
56
86
 
57
- unless result.respond_to?(:failure?)
58
- raise ArgumentError, "#{action_class.name}##{underlying_method}'s result must respond to :failure?"
59
- end
87
+ verify_result_is_conforming!(result, "#{action_class.name}##{underlying_method}")
60
88
 
61
- errors = result.to_h.select { |k, _v| k.to_s.start_with? 'error' }
62
- errors[:error] = "Unknown: Your result doesn't respond to a method beginning with 'error'" unless errors.any?
89
+ errors = result.to_h.select { |key, _value| key.to_s.start_with?('error') }
63
90
  fail!(errors) if result.failure?
64
91
 
65
92
  result
@@ -68,4 +95,12 @@ module Actionizer
68
95
  def respond_to_missing?(method_name, _include_private = false)
69
96
  method_name.to_s.end_with?('_or_fail')
70
97
  end
98
+
99
+ private
100
+
101
+ def verify_result_is_conforming!(result, class_and_method)
102
+ raise ArgumentError, "#{class_and_method}'s result must respond to :to_h" if !result.respond_to?(:to_h)
103
+
104
+ raise ArgumentError, "#{class_and_method}'s result must respond to :failure?" if !result.respond_to?(:failure?)
105
+ end
71
106
  end
@@ -0,0 +1,48 @@
1
+ module Actionizer
2
+ class Inputs
3
+ attr_reader :declared_params_by_method, :method
4
+
5
+ def initialize
6
+ @declared_params_by_method = {}
7
+ end
8
+
9
+ def check_for_param_error(method_name, params = {})
10
+ # If no inputs_for was declared, don't do any checking
11
+ return false if !declared_params_by_method.key?(method_name)
12
+
13
+ params.each_key do |param|
14
+ return "Param #{param} not declared" if !declared_params_by_method.fetch(method_name).include?(param)
15
+ end
16
+
17
+ declared_params_by_method.fetch(method_name, {}).each_pair do |param, attrs|
18
+ next if !attrs.fetch(:required)
19
+
20
+ return "Param #{param} is required for #{method_name}" if !params.include?(param)
21
+ end
22
+
23
+ false
24
+ end
25
+
26
+ def start(method)
27
+ @method = method
28
+ @declared_params_by_method[method] = {}
29
+ end
30
+
31
+ def end
32
+ @method = nil
33
+ end
34
+
35
+ def add(args)
36
+ @declared_params_by_method[method][args.fetch(:param)] = { required: args.fetch(:required) }
37
+ end
38
+
39
+ def no_params_declared?(method)
40
+ declared_params_by_method.fetch(method, {}).empty?
41
+ end
42
+
43
+ def outside_inputs_for_block?
44
+ method.nil?
45
+ end
46
+
47
+ end
48
+ end
@@ -1,3 +1,3 @@
1
1
  module Actionizer
2
- VERSION = '0.7.4'
2
+ VERSION = '0.8.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.4
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Nichols
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-17 00:00:00.000000000 Z
11
+ date: 2016-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -131,6 +131,7 @@ files:
131
131
  - bin/setup
132
132
  - lib/actionizer.rb
133
133
  - lib/actionizer/failure.rb
134
+ - lib/actionizer/inputs.rb
134
135
  - lib/actionizer/result.rb
135
136
  - lib/actionizer/version.rb
136
137
  homepage: https://github.com/mikenichols/actionizer