actionizer 0.7.4 → 0.8.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
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