u-case 3.0.0.rc1

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.
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ class Case
5
+ class Safe < ::Micro::Case
6
+ def self.__flow_builder
7
+ Cases::Safe::Flow
8
+ end
9
+
10
+ def call
11
+ __call
12
+ rescue => exception
13
+ raise exception if Error.by_wrong_usage?(exception)
14
+
15
+ Failure(result: exception)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ class Case
5
+ class Strict < ::Micro::Case
6
+ include Micro::Attributes::Features::StrictInitialize
7
+
8
+ class Safe < ::Micro::Case::Safe
9
+ include Micro::Attributes::Features::StrictInitialize
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ class Case
5
+ module Utils
6
+ def self.symbolize_hash_keys(hash)
7
+ if Kind::Of::Hash(hash).respond_to?(:transform_keys)
8
+ hash.transform_keys { |key| key.to_sym rescue key }
9
+ else
10
+ hash.each_with_object({}) do |(k, v), memo|
11
+ key = k.to_sym rescue k
12
+
13
+ memo[key] = v
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ class Case
5
+ VERSION = '3.0.0.rc1'.freeze
6
+ end
7
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'micro/case'
4
+
5
+ module Micro
6
+ class Case
7
+ include Micro::Attributes::Features::ActiveModelValidations
8
+
9
+ def self.auto_validation_disabled?
10
+ return @disable_auto_validation if defined?(@disable_auto_validation)
11
+ end
12
+
13
+ def self.disable_auto_validation
14
+ @disable_auto_validation = true
15
+ end
16
+
17
+ def initialize(input)
18
+ __setup_use_case(input)
19
+
20
+ run_validations! if respond_to?(:run_validations!, true)
21
+ end
22
+
23
+ private
24
+
25
+ def __call_use_case
26
+ return failure_by_validation_error(self) if !self.class.auto_validation_disabled? && invalid?
27
+
28
+ result = call!
29
+
30
+ return result if result.is_a?(Result)
31
+
32
+ raise Error::UnexpectedResult.new(self.class)
33
+ end
34
+
35
+ def failure_by_validation_error(object)
36
+ errors = object.respond_to?(:errors) ? object.errors : object
37
+
38
+ Failure :validation_error, result: { errors: errors }
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'micro/cases/flow'
4
+ require 'micro/cases/safe/flow'
5
+
6
+ module Micro
7
+ module Cases
8
+ def self.flow(args)
9
+ Flow.build(args)
10
+ end
11
+
12
+ def self.safe_flow(args)
13
+ Safe::Flow.build(args)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ module Cases
5
+ class Flow
6
+ class InvalidUseCases < ArgumentError
7
+ def initialize; super('argument must be a collection of `Micro::Case` classes'.freeze); end
8
+ end
9
+
10
+ attr_reader :use_cases
11
+
12
+ def self.map_use_cases(arg)
13
+ return arg.use_cases if arg.is_a?(Flow)
14
+
15
+ Array(arg)
16
+ end
17
+
18
+ def self.build(args)
19
+ use_cases = Array(args).flat_map { |arg| map_use_cases(arg) }
20
+
21
+ raise InvalidUseCases if use_cases.any? { |klass| !(klass < ::Micro::Case) }
22
+
23
+ new(use_cases)
24
+ end
25
+
26
+ def initialize(use_cases)
27
+ @use_cases = use_cases
28
+ @first_use_case = use_cases[0]
29
+ @next_use_cases = use_cases[1..-1]
30
+ end
31
+
32
+ def call(arg = {})
33
+ memo = arg.is_a?(Hash) ? arg.dup : {}
34
+
35
+ first_result = first_use_case_result(arg)
36
+
37
+ return first_result if @next_use_cases.empty?
38
+
39
+ next_use_cases_result(first_result, memo)
40
+ end
41
+
42
+ def to_proc
43
+ Proc.new { |arg| call(arg) }
44
+ end
45
+
46
+ private
47
+
48
+ def is_a_result?(arg)
49
+ arg.is_a?(Case::Result)
50
+ end
51
+
52
+ def arg_to_call?(arg)
53
+ return true if arg.is_a?(::Micro::Case) || arg.is_a?(Flow)
54
+ return true if arg.is_a?(Class) && arg < ::Micro::Case
55
+ return false
56
+ end
57
+
58
+ def call_arg(arg)
59
+ output = arg.call
60
+
61
+ is_a_result?(output) ? output.value : output
62
+ end
63
+
64
+ def first_use_case_input(arg)
65
+ return call_arg(arg) if arg_to_call?(arg)
66
+ return arg.value if is_a_result?(arg)
67
+
68
+ arg
69
+ end
70
+
71
+ def first_use_case_result(arg)
72
+ input = first_use_case_input(arg)
73
+
74
+ result = Case::Result.new
75
+
76
+ @first_use_case.__call_and_set_transition__(result, input)
77
+ end
78
+
79
+ def next_use_case_result(use_case, result, input)
80
+ use_case.__new__(result, input).call
81
+ end
82
+
83
+ def next_use_cases_result(first_result, memo)
84
+ @next_use_cases.reduce(first_result) do |result, use_case|
85
+ break result if result.failure?
86
+
87
+ memo.merge!(result.value)
88
+
89
+ result.__set_transitions_accessible_attributes__(memo)
90
+
91
+ next_use_case_result(use_case, result, memo)
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ module Cases
5
+ module Safe
6
+ class Flow < Cases::Flow
7
+ private def next_use_case_result(use_case, result, input)
8
+ instance = use_case.__new__(result, input)
9
+ instance.call
10
+ rescue => exception
11
+ raise exception if Case::Error.by_wrong_usage?(exception)
12
+
13
+ result.__set__(false, exception, :exception, instance)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'micro/case'
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kind/active_model/validation'
4
+
5
+ require 'micro/case/with_activemodel_validation'
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ warn 'Deprecation: "u-case/with_validation" will be deprecated in the next major release.' \
4
+ 'Please use "u-case/with_activemodel_validation" instead of it.'
5
+
6
+ require 'u-case/with_activemodel_validation'
data/test.sh ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/bash
2
+
3
+ bundle
4
+
5
+ rm Gemfile.lock
6
+
7
+ source $(dirname $0)/.travis.sh
8
+
9
+ rm Gemfile.lock
10
+
11
+ bundle
@@ -0,0 +1,33 @@
1
+
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'micro/case/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'u-case'
8
+ spec.version = Micro::Case::VERSION
9
+ spec.authors = ['Rodrigo Serradura']
10
+ spec.email = ['rodrigo.serradura@gmail.com']
11
+
12
+ spec.summary = %q{Create simple and powerful use cases as objects.}
13
+ spec.description = %q{Create simple and powerful use cases as objects.}
14
+ spec.homepage = 'https://github.com/serradura/u-case'
15
+ spec.license = 'MIT'
16
+
17
+ raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.' unless spec.respond_to?(:metadata)
18
+
19
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|assets|benchmarks|comparisons|examples)/}) }
21
+ end
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.required_ruby_version = '>= 2.2.0'
27
+
28
+ spec.add_runtime_dependency 'kind', '~> 3.0'
29
+ spec.add_runtime_dependency 'u-attributes', '~> 1.1'
30
+
31
+ spec.add_development_dependency 'bundler'
32
+ spec.add_development_dependency 'rake', '~> 13.0'
33
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: u-case
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.0.0.rc1
5
+ platform: ruby
6
+ authors:
7
+ - Rodrigo Serradura
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-07-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: kind
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: u-attributes
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '13.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '13.0'
69
+ description: Create simple and powerful use cases as objects.
70
+ email:
71
+ - rodrigo.serradura@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".tool-versions"
78
+ - ".travis.sh"
79
+ - ".travis.yml"
80
+ - CODE_OF_CONDUCT.md
81
+ - Gemfile
82
+ - LICENSE.txt
83
+ - README.md
84
+ - Rakefile
85
+ - bin/console
86
+ - bin/setup
87
+ - lib/micro/case.rb
88
+ - lib/micro/case/error.rb
89
+ - lib/micro/case/result.rb
90
+ - lib/micro/case/safe.rb
91
+ - lib/micro/case/strict.rb
92
+ - lib/micro/case/utils.rb
93
+ - lib/micro/case/version.rb
94
+ - lib/micro/case/with_activemodel_validation.rb
95
+ - lib/micro/cases.rb
96
+ - lib/micro/cases/flow.rb
97
+ - lib/micro/cases/safe/flow.rb
98
+ - lib/u-case.rb
99
+ - lib/u-case/with_activemodel_validation.rb
100
+ - lib/u-case/with_validation.rb
101
+ - test.sh
102
+ - u-case.gemspec
103
+ homepage: https://github.com/serradura/u-case
104
+ licenses:
105
+ - MIT
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: 2.2.0
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">"
119
+ - !ruby/object:Gem::Version
120
+ version: 1.3.1
121
+ requirements: []
122
+ rubygems_version: 3.0.6
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: Create simple and powerful use cases as objects.
126
+ test_files: []