interactify 0.2.0.pre.alpha.1 → 0.3.0.pre.RC1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,157 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ interactify (0.3.0.pre.alpha.2)
5
+ interactor
6
+ interactor-contracts
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actionpack (7.0.0)
12
+ actionview (= 7.0.0)
13
+ activesupport (= 7.0.0)
14
+ rack (~> 2.0, >= 2.2.0)
15
+ rack-test (>= 0.6.3)
16
+ rails-dom-testing (~> 2.0)
17
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
18
+ actionview (7.0.0)
19
+ activesupport (= 7.0.0)
20
+ builder (~> 3.1)
21
+ erubi (~> 1.4)
22
+ rails-dom-testing (~> 2.0)
23
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
24
+ activesupport (7.0.0)
25
+ concurrent-ruby (~> 1.0, >= 1.0.2)
26
+ i18n (>= 1.6, < 2)
27
+ minitest (>= 5.1)
28
+ tzinfo (~> 2.0)
29
+ appraisal (2.5.0)
30
+ bundler
31
+ rake
32
+ thor (>= 0.14.0)
33
+ builder (3.2.4)
34
+ concurrent-ruby (1.2.2)
35
+ crass (1.0.6)
36
+ debug (1.9.1)
37
+ irb (~> 1.10)
38
+ reline (>= 0.3.8)
39
+ diff-lcs (1.5.0)
40
+ docile (1.4.0)
41
+ dry-configurable (1.0.1)
42
+ dry-core (~> 1.0, < 2)
43
+ zeitwerk (~> 2.6)
44
+ dry-core (1.0.0)
45
+ concurrent-ruby (~> 1.0)
46
+ zeitwerk (~> 2.6)
47
+ dry-inflector (1.0.0)
48
+ dry-initializer (3.1.1)
49
+ dry-logic (1.5.0)
50
+ concurrent-ruby (~> 1.0)
51
+ dry-core (~> 1.0, < 2)
52
+ zeitwerk (~> 2.6)
53
+ dry-schema (1.13.3)
54
+ concurrent-ruby (~> 1.0)
55
+ dry-configurable (~> 1.0, >= 1.0.1)
56
+ dry-core (~> 1.0, < 2)
57
+ dry-initializer (~> 3.0)
58
+ dry-logic (>= 1.4, < 2)
59
+ dry-types (>= 1.7, < 2)
60
+ zeitwerk (~> 2.6)
61
+ dry-types (1.7.1)
62
+ concurrent-ruby (~> 1.0)
63
+ dry-core (~> 1.0)
64
+ dry-inflector (~> 1.0)
65
+ dry-logic (~> 1.4)
66
+ zeitwerk (~> 2.6)
67
+ dry-validation (1.10.0)
68
+ concurrent-ruby (~> 1.0)
69
+ dry-core (~> 1.0, < 2)
70
+ dry-initializer (~> 3.0)
71
+ dry-schema (>= 1.12, < 2)
72
+ zeitwerk (~> 2.6)
73
+ erubi (1.12.0)
74
+ i18n (1.14.1)
75
+ concurrent-ruby (~> 1.0)
76
+ interactor (3.1.2)
77
+ interactor-contracts (0.3.0)
78
+ dry-validation (~> 1.0)
79
+ interactor (~> 3)
80
+ io-console (0.7.1)
81
+ irb (1.11.0)
82
+ rdoc
83
+ reline (>= 0.3.8)
84
+ loofah (2.22.0)
85
+ crass (~> 1.0.2)
86
+ nokogiri (>= 1.12.0)
87
+ method_source (1.0.0)
88
+ mini_portile2 (2.8.5)
89
+ minitest (5.20.0)
90
+ nokogiri (1.15.5)
91
+ mini_portile2 (~> 2.8.2)
92
+ racc (~> 1.4)
93
+ psych (5.1.2)
94
+ stringio
95
+ racc (1.7.3)
96
+ rack (2.2.8)
97
+ rack-test (2.1.0)
98
+ rack (>= 1.3)
99
+ rails-dom-testing (2.2.0)
100
+ activesupport (>= 5.0.0)
101
+ minitest
102
+ nokogiri (>= 1.6)
103
+ rails-html-sanitizer (1.6.0)
104
+ loofah (~> 2.21)
105
+ nokogiri (~> 1.14)
106
+ railties (7.0.0)
107
+ actionpack (= 7.0.0)
108
+ activesupport (= 7.0.0)
109
+ method_source
110
+ rake (>= 12.2)
111
+ thor (~> 1.0)
112
+ zeitwerk (~> 2.5)
113
+ rake (13.1.0)
114
+ rdoc (6.6.2)
115
+ psych (>= 4.0.0)
116
+ reline (0.4.1)
117
+ io-console (~> 0.5)
118
+ rspec (3.12.0)
119
+ rspec-core (~> 3.12.0)
120
+ rspec-expectations (~> 3.12.0)
121
+ rspec-mocks (~> 3.12.0)
122
+ rspec-core (3.12.2)
123
+ rspec-support (~> 3.12.0)
124
+ rspec-expectations (3.12.3)
125
+ diff-lcs (>= 1.2.0, < 2.0)
126
+ rspec-support (~> 3.12.0)
127
+ rspec-mocks (3.12.6)
128
+ diff-lcs (>= 1.2.0, < 2.0)
129
+ rspec-support (~> 3.12.0)
130
+ rspec-support (3.12.1)
131
+ simplecov (0.22.0)
132
+ docile (~> 1.1)
133
+ simplecov-html (~> 0.11)
134
+ simplecov_json_formatter (~> 0.1)
135
+ simplecov-html (0.12.3)
136
+ simplecov_json_formatter (0.1.4)
137
+ stringio (3.1.0)
138
+ thor (1.3.0)
139
+ tzinfo (2.0.6)
140
+ concurrent-ruby (~> 1.0)
141
+ zeitwerk (2.6.12)
142
+
143
+ PLATFORMS
144
+ ruby
145
+
146
+ DEPENDENCIES
147
+ appraisal
148
+ bundler (~> 2.0)
149
+ debug
150
+ interactify!
151
+ railties (= 7)
152
+ rake (~> 13.0)
153
+ rspec (~> 3.0)
154
+ simplecov
155
+
156
+ BUNDLED WITH
157
+ 2.4.22
@@ -0,0 +1,18 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake", "~> 13.0"
6
+ gem "railties", "7"
7
+ gem "sidekiq", "7"
8
+
9
+ group :development do
10
+ gem "bundler", "~> 2.0"
11
+ end
12
+
13
+ group :test do
14
+ gem "simplecov", require: false
15
+ gem "rspec", "~> 3.0"
16
+ end
17
+
18
+ gemspec path: "../"
@@ -0,0 +1,166 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ interactify (0.3.0.pre.alpha.2)
5
+ interactor
6
+ interactor-contracts
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actionpack (7.0.0)
12
+ actionview (= 7.0.0)
13
+ activesupport (= 7.0.0)
14
+ rack (~> 2.0, >= 2.2.0)
15
+ rack-test (>= 0.6.3)
16
+ rails-dom-testing (~> 2.0)
17
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
18
+ actionview (7.0.0)
19
+ activesupport (= 7.0.0)
20
+ builder (~> 3.1)
21
+ erubi (~> 1.4)
22
+ rails-dom-testing (~> 2.0)
23
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
24
+ activesupport (7.0.0)
25
+ concurrent-ruby (~> 1.0, >= 1.0.2)
26
+ i18n (>= 1.6, < 2)
27
+ minitest (>= 5.1)
28
+ tzinfo (~> 2.0)
29
+ appraisal (2.5.0)
30
+ bundler
31
+ rake
32
+ thor (>= 0.14.0)
33
+ builder (3.2.4)
34
+ concurrent-ruby (1.2.2)
35
+ connection_pool (2.4.1)
36
+ crass (1.0.6)
37
+ debug (1.9.1)
38
+ irb (~> 1.10)
39
+ reline (>= 0.3.8)
40
+ diff-lcs (1.5.0)
41
+ docile (1.4.0)
42
+ dry-configurable (1.0.1)
43
+ dry-core (~> 1.0, < 2)
44
+ zeitwerk (~> 2.6)
45
+ dry-core (1.0.0)
46
+ concurrent-ruby (~> 1.0)
47
+ zeitwerk (~> 2.6)
48
+ dry-inflector (1.0.0)
49
+ dry-initializer (3.1.1)
50
+ dry-logic (1.5.0)
51
+ concurrent-ruby (~> 1.0)
52
+ dry-core (~> 1.0, < 2)
53
+ zeitwerk (~> 2.6)
54
+ dry-schema (1.13.3)
55
+ concurrent-ruby (~> 1.0)
56
+ dry-configurable (~> 1.0, >= 1.0.1)
57
+ dry-core (~> 1.0, < 2)
58
+ dry-initializer (~> 3.0)
59
+ dry-logic (>= 1.4, < 2)
60
+ dry-types (>= 1.7, < 2)
61
+ zeitwerk (~> 2.6)
62
+ dry-types (1.7.1)
63
+ concurrent-ruby (~> 1.0)
64
+ dry-core (~> 1.0)
65
+ dry-inflector (~> 1.0)
66
+ dry-logic (~> 1.4)
67
+ zeitwerk (~> 2.6)
68
+ dry-validation (1.10.0)
69
+ concurrent-ruby (~> 1.0)
70
+ dry-core (~> 1.0, < 2)
71
+ dry-initializer (~> 3.0)
72
+ dry-schema (>= 1.12, < 2)
73
+ zeitwerk (~> 2.6)
74
+ erubi (1.12.0)
75
+ i18n (1.14.1)
76
+ concurrent-ruby (~> 1.0)
77
+ interactor (3.1.2)
78
+ interactor-contracts (0.3.0)
79
+ dry-validation (~> 1.0)
80
+ interactor (~> 3)
81
+ io-console (0.7.1)
82
+ irb (1.11.0)
83
+ rdoc
84
+ reline (>= 0.3.8)
85
+ loofah (2.22.0)
86
+ crass (~> 1.0.2)
87
+ nokogiri (>= 1.12.0)
88
+ method_source (1.0.0)
89
+ mini_portile2 (2.8.5)
90
+ minitest (5.20.0)
91
+ nokogiri (1.15.5)
92
+ mini_portile2 (~> 2.8.2)
93
+ racc (~> 1.4)
94
+ psych (5.1.2)
95
+ stringio
96
+ racc (1.7.3)
97
+ rack (2.2.8)
98
+ rack-test (2.1.0)
99
+ rack (>= 1.3)
100
+ rails-dom-testing (2.2.0)
101
+ activesupport (>= 5.0.0)
102
+ minitest
103
+ nokogiri (>= 1.6)
104
+ rails-html-sanitizer (1.6.0)
105
+ loofah (~> 2.21)
106
+ nokogiri (~> 1.14)
107
+ railties (7.0.0)
108
+ actionpack (= 7.0.0)
109
+ activesupport (= 7.0.0)
110
+ method_source
111
+ rake (>= 12.2)
112
+ thor (~> 1.0)
113
+ zeitwerk (~> 2.5)
114
+ rake (13.1.0)
115
+ rdoc (6.6.2)
116
+ psych (>= 4.0.0)
117
+ redis-client (0.19.1)
118
+ connection_pool
119
+ reline (0.4.1)
120
+ io-console (~> 0.5)
121
+ rspec (3.12.0)
122
+ rspec-core (~> 3.12.0)
123
+ rspec-expectations (~> 3.12.0)
124
+ rspec-mocks (~> 3.12.0)
125
+ rspec-core (3.12.2)
126
+ rspec-support (~> 3.12.0)
127
+ rspec-expectations (3.12.3)
128
+ diff-lcs (>= 1.2.0, < 2.0)
129
+ rspec-support (~> 3.12.0)
130
+ rspec-mocks (3.12.6)
131
+ diff-lcs (>= 1.2.0, < 2.0)
132
+ rspec-support (~> 3.12.0)
133
+ rspec-support (3.12.1)
134
+ sidekiq (7.0.0)
135
+ concurrent-ruby (< 2)
136
+ connection_pool (>= 2.3.0)
137
+ rack (>= 2.2.4)
138
+ redis-client (>= 0.9.0)
139
+ simplecov (0.22.0)
140
+ docile (~> 1.1)
141
+ simplecov-html (~> 0.11)
142
+ simplecov_json_formatter (~> 0.1)
143
+ simplecov-html (0.12.3)
144
+ simplecov_json_formatter (0.1.4)
145
+ stringio (3.1.0)
146
+ thor (1.3.0)
147
+ tzinfo (2.0.6)
148
+ concurrent-ruby (~> 1.0)
149
+ zeitwerk (2.6.12)
150
+
151
+ PLATFORMS
152
+ ruby
153
+
154
+ DEPENDENCIES
155
+ appraisal
156
+ bundler (~> 2.0)
157
+ debug
158
+ interactify!
159
+ railties (= 7)
160
+ rake (~> 13.0)
161
+ rspec (~> 3.0)
162
+ sidekiq (= 7)
163
+ simplecov
164
+
165
+ BUNDLED WITH
166
+ 2.4.22
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "interactify/jobable"
4
4
  require "interactify/call_wrapper"
5
- require "interactify/organizer_call_monkey_patch"
5
+ require "interactify/organizer"
6
6
  require "interactify/contract_failure"
7
7
 
8
8
  module Interactify
@@ -48,7 +48,7 @@ module Interactify
48
48
  # failure class: Whatever::SomeInteractor::InteractorContractFailure
49
49
  const_set "InteractorContractFailure", c
50
50
  prepend CallWrapper
51
- include OrganizerCallMonkeyPatch if ancestors.include? Interactor::Organizer
51
+ include Organizer
52
52
 
53
53
  on_breach do |breaches|
54
54
  breaches = breaches.map { |b| { b.property => b.messages } }.inject(&:merge)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "interactify/each_chain"
4
4
  require "interactify/if_interactor"
5
+ require "interactify/unique_klass_name"
5
6
 
6
7
  module Interactify
7
8
  module Dsl
@@ -63,6 +64,7 @@ module Interactify
63
64
 
64
65
  # attach the class to the calling namespace
65
66
  where_to_attach = self.binding.receiver
67
+ klass_name = UniqueKlassName.for(where_to_attach, klass_name)
66
68
  where_to_attach.const_set(klass_name, klass)
67
69
  end
68
70
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "interactify/unique_klass_name"
4
+
3
5
  module Interactify
4
6
  class EachChain
5
7
  attr_reader :each_loop_klasses, :plural_resource_name, :evaluating_receiver
@@ -38,7 +40,7 @@ module Interactify
38
40
  context[this.singular_resource_name] = resource # context.package = package
39
41
  context[this.singular_resource_index_name] = index # context.package_index = index
40
42
 
41
- klasses = self.class.wrap_lambdas_in_interactors(this.each_loop_klasses)
43
+ klasses = InteractorWrapper.wrap_many(self, this.each_loop_klasses)
42
44
 
43
45
  klasses.each do |interactor| # [A, B, C].each do |interactor|
44
46
  interactor.call!(context) # interactor.call!(context)
@@ -59,8 +61,10 @@ module Interactify
59
61
  # rubocop:enable all
60
62
 
61
63
  def attach_klass
62
- namespace.const_set(iterator_klass_name, klass)
63
- namespace.const_get(iterator_klass_name)
64
+ name = iterator_klass_name
65
+
66
+ namespace.const_set(name, klass)
67
+ namespace.const_get(name)
64
68
  end
65
69
 
66
70
  def namespace
@@ -68,7 +72,9 @@ module Interactify
68
72
  end
69
73
 
70
74
  def iterator_klass_name
71
- :"Each#{singular_resource_name.to_s.camelize}".to_sym
75
+ prefix = "Each#{singular_resource_name.to_s.camelize}"
76
+
77
+ UniqueKlassName.for(namespace, prefix)
72
78
  end
73
79
 
74
80
  def singular_resource_name
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "interactify/unique_klass_name"
4
+
3
5
  module Interactify
4
6
  class IfInteractor
5
7
  attr_reader :condition, :success_interactor, :failure_interactor, :evaluating_receiver
@@ -49,8 +51,9 @@ module Interactify
49
51
  # rubocop:enable all
50
52
 
51
53
  def attach_klass
52
- namespace.const_set(if_klass_name, klass)
53
- namespace.const_get(if_klass_name)
54
+ name = if_klass_name
55
+ namespace.const_set(name, klass)
56
+ namespace.const_get(name)
54
57
  end
55
58
 
56
59
  def namespace
@@ -58,9 +61,10 @@ module Interactify
58
61
  end
59
62
 
60
63
  def if_klass_name
61
- name = condition.is_a?(Proc) ? "Proc" : condition
64
+ prefix = condition.is_a?(Proc) ? "Proc" : condition
65
+ prefix = "If#{prefix.to_s.camelize}"
62
66
 
63
- "If#{name.to_s.camelize}".to_sym
67
+ UniqueKlassName.for(namespace, prefix)
64
68
  end
65
69
  end
66
70
  end
@@ -67,7 +67,7 @@ module Interactify
67
67
 
68
68
  def interactor_klass?(object)
69
69
  return unless object.is_a?(Class) && object.ancestors.include?(Interactor)
70
- return if object.is_a?(Sidekiq::Job)
70
+ return if Interactify.sidekiq? && object.is_a?(Sidekiq::Job)
71
71
 
72
72
  true
73
73
  end
@@ -116,9 +116,9 @@ module Interactify
116
116
  .gsub(root.to_s, "") # "/namespace/sub_namespace/class_name.rb"
117
117
  .gsub("/concerns", "") # concerns directory is ignored by Zeitwerk
118
118
  .split("/") # "['', 'namespace', 'sub_namespace', 'class_name.rb']
119
- .compact_blank # "['namespace', 'sub_namespace', 'class_name.rb']
119
+ .reject(&:blank?) # "['namespace', 'sub_namespace', 'class_name.rb']
120
120
  .join("/") # 'namespace/sub_namespace/class_name.rb'
121
- .gsub(/\.rb\z/, "") # 'namespace/sub_namespace/class_name'
121
+ .gsub(/\.rb\z/, "") # 'namespace/sub_namespace/class_name'
122
122
  end
123
123
  end
124
124
  end
@@ -10,7 +10,7 @@ module Interactify
10
10
  class InteractorWiring
11
11
  attr_reader :root, :ignore
12
12
 
13
- def initialize(root: Rails.root, ignore: [])
13
+ def initialize(root:, ignore: [])
14
14
  @root = root.to_s.gsub(%r{/$}, "")
15
15
  @ignore = ignore
16
16
  end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "interactify/unique_klass_name"
4
+
5
+ module Interactify
6
+ class InteractorWrapper
7
+ attr_reader :organizer, :interactor
8
+
9
+ def self.wrap_many(organizer, interactors)
10
+ Array(interactors).map do |interactor|
11
+ wrap(organizer, interactor)
12
+ end
13
+ end
14
+
15
+ def self.wrap(organizer, interactor)
16
+ new(organizer, interactor).wrap
17
+ end
18
+
19
+ def initialize(organizer, interactor)
20
+ @organizer = organizer
21
+ @interactor = interactor
22
+ end
23
+
24
+ def wrap
25
+ case interactor
26
+ when Hash
27
+ wrap_conditional
28
+ when Array
29
+ wrap_chain
30
+ when Proc
31
+ wrap_proc
32
+ else
33
+ interactor
34
+ end
35
+ end
36
+
37
+ def wrap_chain
38
+ return self.class.wrap(organizer, interactor.first) if interactor.length == 1
39
+
40
+ klass_name = UniqueKlassName.for(organizer, "Chained")
41
+ organizer.chain(klass_name, *interactor.map { self.class.wrap(organizer, _1) })
42
+ end
43
+
44
+ def wrap_conditional
45
+ raise ArgumentError, "Hash must have at least :if, and :then key" unless condition && then_do
46
+
47
+ return organizer.if(condition, then_do, else_do) if else_do
48
+
49
+ organizer.if(condition, then_do)
50
+ end
51
+
52
+ def condition = interactor[:if]
53
+ def then_do = interactor[:then]
54
+ def else_do = interactor[:else]
55
+
56
+ def wrap_proc
57
+ this = self
58
+
59
+ Class.new do
60
+ include Interactify
61
+
62
+ define_singleton_method :wrapped do
63
+ this.interactor
64
+ end
65
+
66
+ define_method(:call) do
67
+ this.interactor.call(context)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "sidekiq"
4
- require "sidekiq/job"
5
-
6
3
  require "interactify/async_job_klass"
4
+ require "interactify/null_job"
7
5
 
8
6
  module Interactify
9
7
  class JobMaker
@@ -24,6 +22,8 @@ module Interactify
24
22
  private
25
23
 
26
24
  def define_job_klass
25
+ return NullJob if Interactify.sidekiq_missing?
26
+
27
27
  this = self
28
28
 
29
29
  invalid_keys = this.opts.symbolize_keys.keys - %i[queue retry dead backtrace pool tags]
@@ -11,6 +11,8 @@ module Interactify
11
11
  #
12
12
  # then let's make sure to define Klass::Job separately
13
13
  included do |base|
14
+ next if Interactify.sidekiq_missing?
15
+
14
16
  def base.inherited(klass)
15
17
  super_klass = klass.superclass
16
18
  super_job = super_klass::Job # really spiffing
@@ -0,0 +1,11 @@
1
+ module Interactify
2
+ class NullJob
3
+ def method_missing(...)
4
+ self
5
+ end
6
+
7
+ def self.method_missing(...)
8
+ self
9
+ end
10
+ end
11
+ end
@@ -1,32 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "interactify/interactor_wrapper"
4
+
3
5
  module Interactify
4
- module OrganizerCallMonkeyPatch
6
+ module Organizer
5
7
  extend ActiveSupport::Concern
6
8
 
7
9
  class_methods do
8
10
  def organize(*interactors)
9
- wrapped = wrap_lambdas_in_interactors(interactors)
11
+ wrapped = InteractorWrapper.wrap_many(self, interactors)
10
12
 
11
13
  super(*wrapped)
12
14
  end
13
-
14
- def wrap_lambdas_in_interactors(interactors)
15
- Array(interactors).map do |interactor|
16
- case interactor
17
- when Proc
18
- Class.new do
19
- include Interactify
20
-
21
- define_method(:call) do
22
- interactor.call(context)
23
- end
24
- end
25
- else
26
- interactor
27
- end
28
- end
29
- end
30
15
  end
31
16
 
32
17
  def call
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Interactify
4
+ module UniqueKlassName
5
+ def self.for(namespace, prefix)
6
+ id = generate_unique_id
7
+ klass_name = :"#{prefix}#{id}"
8
+
9
+ while namespace.const_defined?(klass_name)
10
+ id = generate_unique_id
11
+ klass_name = :"#{prefix}#{id}"
12
+ end
13
+
14
+ klass_name.to_sym
15
+ end
16
+
17
+ def self.generate_unique_id
18
+ rand(10_000)
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Interactify
4
- VERSION = "0.2.0-alpha.1"
4
+ VERSION = "0.3.0-RC1"
5
5
  end