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 +4 -4
- data/.rubocop.yml +5 -1
- data/lib/actionizer.rb +42 -7
- data/lib/actionizer/inputs.rb +48 -0
- data/lib/actionizer/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a63a9ba128ed80a4d5090ddb1934f44a5281387f
|
4
|
+
data.tar.gz: b8d54516906e1766cefebc20e31c4831f9b95dd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4aa44e386f9957c7f52177084fb9e60d0ba3b0fe572f5eef09f30be13e62732059489f8e4927319e0554d27ea2b4c4538bc618f5e0df0e26315dff1dcdeb2432
|
7
|
+
data.tar.gz: ea3037ed552d5d9ae3b5aeb3ce37cef181c9a9cc612b18386e3abf3d2790ece33a3eb31c449c322d61c1c401107e49ba346525341e4a7e13b33c94e2a754a3bf
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
Metrics/AbcSize:
|
2
|
-
Max:
|
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
|
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
|
-
|
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
|
-
|
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 { |
|
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
|
data/lib/actionizer/version.rb
CHANGED
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.
|
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-
|
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
|