servactory 1.5.2 → 1.6.1

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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -394
  3. data/config/locales/en.yml +5 -5
  4. data/lib/servactory/base.rb +4 -4
  5. data/lib/servactory/configuration/factory.rb +10 -6
  6. data/lib/servactory/configuration/setup.rb +10 -7
  7. data/lib/servactory/context/callable.rb +21 -22
  8. data/lib/servactory/context/workspace/inputs.rb +13 -0
  9. data/lib/servactory/context/workspace.rb +9 -7
  10. data/lib/servactory/errors/base.rb +2 -1
  11. data/lib/servactory/errors/collection.rb +25 -0
  12. data/lib/servactory/errors/failure.rb +11 -1
  13. data/lib/servactory/errors/input_error.rb +17 -0
  14. data/lib/servactory/errors/internal_error.rb +15 -0
  15. data/lib/servactory/errors/output_error.rb +15 -0
  16. data/lib/servactory/{input_arguments → inputs}/checks/base.rb +3 -3
  17. data/lib/servactory/{input_arguments → inputs}/checks/errors.rb +1 -1
  18. data/lib/servactory/{input_arguments → inputs}/checks/inclusion.rb +2 -2
  19. data/lib/servactory/{input_arguments → inputs}/checks/must.rb +3 -3
  20. data/lib/servactory/{input_arguments → inputs}/checks/required.rb +2 -2
  21. data/lib/servactory/{input_arguments → inputs}/checks/type.rb +3 -3
  22. data/lib/servactory/{input_arguments → inputs}/collection.rb +1 -1
  23. data/lib/servactory/{input_arguments → inputs}/define_input_conflict.rb +1 -1
  24. data/lib/servactory/{input_arguments → inputs}/define_input_method.rb +1 -1
  25. data/lib/servactory/inputs/dsl.rb +36 -0
  26. data/lib/servactory/{input_arguments/input_argument.rb → inputs/input.rb} +12 -12
  27. data/lib/servactory/{input_arguments → inputs}/option.rb +5 -3
  28. data/lib/servactory/{input_arguments → inputs}/options_collection.rb +1 -1
  29. data/lib/servactory/{input_arguments → inputs}/tools/check.rb +5 -5
  30. data/lib/servactory/{input_arguments → inputs}/tools/check_errors.rb +1 -1
  31. data/lib/servactory/{input_arguments → inputs}/tools/find_unnecessary.rb +6 -6
  32. data/lib/servactory/{input_arguments → inputs}/tools/prepare.rb +5 -5
  33. data/lib/servactory/inputs/tools/rules.rb +46 -0
  34. data/lib/servactory/{input_arguments → inputs}/workbench.rb +8 -8
  35. data/lib/servactory/internals/checks/base.rb +17 -0
  36. data/lib/servactory/{internal_arguments → internals}/checks/type.rb +8 -8
  37. data/lib/servactory/{output_arguments → internals}/collection.rb +1 -1
  38. data/lib/servactory/internals/dsl.rb +33 -0
  39. data/lib/servactory/{internal_arguments/internal_argument.rb → internals/internal.rb} +2 -2
  40. data/lib/servactory/internals/tools/prepare.rb +60 -0
  41. data/lib/servactory/{internal_arguments → internals}/workbench.rb +5 -5
  42. data/lib/servactory/{make_methods → methods}/collection.rb +1 -1
  43. data/lib/servactory/methods/dsl.rb +47 -0
  44. data/lib/servactory/{make_methods/make_method.rb → methods/method.rb} +2 -2
  45. data/lib/servactory/methods/shortcuts/collection.rb +17 -0
  46. data/lib/servactory/{make_methods → methods}/workbench.rb +6 -6
  47. data/lib/servactory/outputs/checks/base.rb +17 -0
  48. data/lib/servactory/{output_arguments → outputs}/checks/type.rb +8 -8
  49. data/lib/servactory/{internal_arguments → outputs}/collection.rb +1 -1
  50. data/lib/servactory/outputs/dsl.rb +33 -0
  51. data/lib/servactory/{output_arguments/output_argument.rb → outputs/output.rb} +2 -2
  52. data/lib/servactory/{output_arguments → outputs}/tools/conflicts.rb +7 -7
  53. data/lib/servactory/outputs/tools/prepare.rb +62 -0
  54. data/lib/servactory/outputs/workbench.rb +31 -0
  55. data/lib/servactory/result.rb +4 -4
  56. data/lib/servactory/utils.rb +2 -0
  57. data/lib/servactory/version.rb +2 -2
  58. metadata +60 -47
  59. data/lib/servactory/context/configuration.rb +0 -23
  60. data/lib/servactory/context/workspace/error.rb +0 -19
  61. data/lib/servactory/context/workspace/errors.rb +0 -33
  62. data/lib/servactory/errors/input_argument_error.rb +0 -7
  63. data/lib/servactory/errors/internal_argument_error.rb +0 -7
  64. data/lib/servactory/errors/output_argument_error.rb +0 -7
  65. data/lib/servactory/input_arguments/dsl.rb +0 -36
  66. data/lib/servactory/input_arguments/tools/rules.rb +0 -43
  67. data/lib/servactory/inputs.rb +0 -9
  68. data/lib/servactory/internal_arguments/checks/base.rb +0 -17
  69. data/lib/servactory/internal_arguments/dsl.rb +0 -33
  70. data/lib/servactory/internal_arguments/tools/prepare.rb +0 -60
  71. data/lib/servactory/make_methods/dsl.rb +0 -33
  72. data/lib/servactory/output_arguments/checks/base.rb +0 -17
  73. data/lib/servactory/output_arguments/dsl.rb +0 -33
  74. data/lib/servactory/output_arguments/tools/prepare.rb +0 -62
  75. data/lib/servactory/output_arguments/workbench.rb +0 -31
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Internals
5
+ module DSL
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ def inherited(child)
12
+ super
13
+
14
+ child.send(:collection_of_internals).merge(collection_of_internals)
15
+ end
16
+
17
+ private
18
+
19
+ def internal(name, **options)
20
+ collection_of_internals << Internal.new(name, **options)
21
+ end
22
+
23
+ def collection_of_internals
24
+ @collection_of_internals ||= Collection.new
25
+ end
26
+
27
+ def internals_workbench
28
+ @internals_workbench ||= Workbench.work_with(collection_of_internals)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servactory
4
- module InternalArguments
5
- class InternalArgument
4
+ module Internals
5
+ class Internal
6
6
  attr_reader :name,
7
7
  :types,
8
8
  :required
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Internals
5
+ module Tools
6
+ class Prepare
7
+ def self.prepare(...)
8
+ new(...).prepare
9
+ end
10
+
11
+ def initialize(context, collection_of_internals)
12
+ @context = context
13
+ @collection_of_internals = collection_of_internals
14
+ end
15
+
16
+ def prepare
17
+ @collection_of_internals.each do |internal|
18
+ create_instance_variable_for(internal)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def create_instance_variable_for(internal)
25
+ @context.instance_variable_set(:"@#{internal.name}", nil)
26
+
27
+ @context.class.class_eval(context_internal_template_for(internal))
28
+ end
29
+
30
+ # EXAMPLE:
31
+ #
32
+ # define_method(:user=) do |value|
33
+ # Servactory::Internals::Checks::Type.check!( context: self, internal:, value: )
34
+ #
35
+ # instance_variable_set(:@user, value)
36
+ # end
37
+ #
38
+ # private attr_reader :user
39
+ #
40
+ def context_internal_template_for(internal)
41
+ <<-RUBY
42
+ define_method(:#{internal.name}=) do |value|
43
+ Servactory::Internals::Checks::Type.check!(
44
+ context: self,
45
+ internal: internal,
46
+ value: value
47
+ )
48
+
49
+ instance_variable_set(:@#{internal.name}, value)
50
+ end
51
+
52
+ private
53
+
54
+ attr_reader :#{internal.name}
55
+ RUBY
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servactory
4
- module InternalArguments
4
+ module Internals
5
5
  class Workbench
6
6
  def self.work_with(...)
7
7
  new(...)
8
8
  end
9
9
 
10
- def initialize(collection_of_internal_arguments)
11
- @collection_of_internal_arguments = collection_of_internal_arguments
10
+ def initialize(collection_of_internals)
11
+ @collection_of_internals = collection_of_internals
12
12
  end
13
13
 
14
14
  def assign(context:)
@@ -16,13 +16,13 @@ module Servactory
16
16
  end
17
17
 
18
18
  def prepare
19
- Tools::Prepare.prepare(context, collection_of_internal_arguments)
19
+ Tools::Prepare.prepare(context, collection_of_internals)
20
20
  end
21
21
 
22
22
  private
23
23
 
24
24
  attr_reader :context,
25
- :collection_of_internal_arguments
25
+ :collection_of_internals
26
26
  end
27
27
  end
28
28
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servactory
4
- module MakeMethods
4
+ module Methods
5
5
  class Collection
6
6
  # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
7
7
  extend Forwardable
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Methods
5
+ module DSL
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ def inherited(child)
12
+ super
13
+
14
+ child.send(:collection_of_methods).merge(collection_of_methods)
15
+ end
16
+
17
+ private
18
+
19
+ def make(name, **options)
20
+ collection_of_methods << Method.new(name, **options)
21
+ end
22
+
23
+ def method_missing(shortcut_name, *args, &block)
24
+ return super unless Servactory.configuration.method_shortcuts.include?(shortcut_name)
25
+
26
+ method_options = args.last.is_a?(Hash) ? args.pop : {}
27
+
28
+ args.each do |method_name|
29
+ make(:"#{shortcut_name}_#{method_name}", **method_options)
30
+ end
31
+ end
32
+
33
+ def respond_to_missing?(shortcut_name, *)
34
+ Servactory.configuration.method_shortcuts.include?(shortcut_name) || super
35
+ end
36
+
37
+ def collection_of_methods
38
+ @collection_of_methods ||= Collection.new
39
+ end
40
+
41
+ def methods_workbench
42
+ @methods_workbench ||= Workbench.work_with(collection_of_methods)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servactory
4
- module MakeMethods
5
- class MakeMethod
4
+ module Methods
5
+ class Method
6
6
  attr_reader :name,
7
7
  :condition
8
8
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Methods
5
+ module Shortcuts
6
+ class Collection
7
+ # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
8
+ extend Forwardable
9
+ def_delegators :@collection, :<<, :each, :merge, :include?
10
+
11
+ def initialize(*)
12
+ @collection = Set.new
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servactory
4
- module MakeMethods
4
+ module Methods
5
5
  class Workbench
6
6
  def self.work_with(...)
7
7
  new(...)
8
8
  end
9
9
 
10
- def initialize(collection_of_make_methods)
11
- @collection_of_make_methods = collection_of_make_methods
10
+ def initialize(collection_of_methods)
11
+ @collection_of_methods = collection_of_methods
12
12
  end
13
13
 
14
14
  def assign(context:)
@@ -16,7 +16,7 @@ module Servactory
16
16
  end
17
17
 
18
18
  def run!
19
- collection_of_make_methods.each do |make_method|
19
+ collection_of_methods.each do |make_method|
20
20
  next if unnecessary_for?(make_method)
21
21
 
22
22
  context.send(make_method.name)
@@ -26,7 +26,7 @@ module Servactory
26
26
  private
27
27
 
28
28
  attr_reader :context,
29
- :collection_of_make_methods
29
+ :collection_of_methods
30
30
 
31
31
  def unnecessary_for?(make_method)
32
32
  condition = make_method.condition
@@ -34,7 +34,7 @@ module Servactory
34
34
  return false if condition.blank?
35
35
  return !Servactory::Utils.boolean?(condition) unless condition.is_a?(Proc)
36
36
 
37
- !condition.call(context)
37
+ !condition.call(context: context)
38
38
  end
39
39
  end
40
40
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Outputs
5
+ module Checks
6
+ class Base
7
+ protected
8
+
9
+ def raise_error_with(message, **attributes)
10
+ message = message.call(**attributes) if message.is_a?(Proc)
11
+
12
+ raise Servactory.configuration.output_error_class.new(message: message)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servactory
4
- module OutputArguments
4
+ module Outputs
5
5
  module Checks
6
6
  class Type < Base
7
- DEFAULT_MESSAGE = lambda do |service_class_name:, output_argument:, expected_type:, given_type:|
7
+ DEFAULT_MESSAGE = lambda do |service_class_name:, output:, expected_type:, given_type:|
8
8
  I18n.t(
9
- "servactory.output_arguments.checks.type.default_error",
9
+ "servactory.outputs.checks.type.default_error",
10
10
  service_class_name: service_class_name,
11
- output_argument_name: output_argument.name,
11
+ output_name: output.name,
12
12
  expected_type: expected_type,
13
13
  given_type: given_type
14
14
  )
@@ -22,11 +22,11 @@ module Servactory
22
22
 
23
23
  ##########################################################################
24
24
 
25
- def initialize(context:, output_argument:, value:)
25
+ def initialize(context:, output:, value:)
26
26
  super()
27
27
 
28
28
  @context = context
29
- @output_argument = output_argument
29
+ @output = output
30
30
  @value = value
31
31
  end
32
32
 
@@ -36,7 +36,7 @@ module Servactory
36
36
  raise_error_with(
37
37
  DEFAULT_MESSAGE,
38
38
  service_class_name: @context.class.name,
39
- output_argument: @output_argument,
39
+ output: @output,
40
40
  expected_type: prepared_types.join(", "),
41
41
  given_type: @value.class.name
42
42
  )
@@ -46,7 +46,7 @@ module Servactory
46
46
 
47
47
  def prepared_types
48
48
  @prepared_types ||=
49
- Array(@output_argument.types).map do |type|
49
+ Array(@output.types).map do |type|
50
50
  if type.is_a?(String)
51
51
  Object.const_get(type)
52
52
  else
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servactory
4
- module InternalArguments
4
+ module Outputs
5
5
  class Collection
6
6
  # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
7
7
  extend Forwardable
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Outputs
5
+ module DSL
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ def inherited(child)
12
+ super
13
+
14
+ child.send(:collection_of_outputs).merge(collection_of_outputs)
15
+ end
16
+
17
+ private
18
+
19
+ def output(name, **options)
20
+ collection_of_outputs << Output.new(name, **options)
21
+ end
22
+
23
+ def collection_of_outputs
24
+ @collection_of_outputs ||= Collection.new
25
+ end
26
+
27
+ def outputs_workbench
28
+ @outputs_workbench ||= Workbench.work_with(collection_of_outputs)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servactory
4
- module OutputArguments
5
- class OutputArgument
4
+ module Outputs
5
+ class Output
6
6
  attr_reader :name,
7
7
  :types,
8
8
  :required,
@@ -1,36 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servactory
4
- module OutputArguments
4
+ module Outputs
5
5
  module Tools
6
6
  class Conflicts
7
7
  def self.check!(...)
8
8
  new(...).check!
9
9
  end
10
10
 
11
- def initialize(context, collection_of_output_arguments, collection_of_internal_arguments)
11
+ def initialize(context, collection_of_outputs, collection_of_internals)
12
12
  @context = context
13
- @collection_of_output_arguments = collection_of_output_arguments
14
- @collection_of_internal_arguments = collection_of_internal_arguments
13
+ @collection_of_outputs = collection_of_outputs
14
+ @collection_of_internals = collection_of_internals
15
15
  end
16
16
 
17
17
  def check!
18
18
  return if overlapping_attributes.empty?
19
19
 
20
20
  message_text = I18n.t(
21
- "servactory.output_arguments.tools.conflicts.error",
21
+ "servactory.outputs.tools.conflicts.error",
22
22
  service_class_name: @context.class.name,
23
23
  overlapping_attributes: overlapping_attributes.join(", ")
24
24
  )
25
25
 
26
- raise Servactory.configuration.output_argument_error_class, message_text
26
+ raise Servactory.configuration.output_error_class.new(message: message_text)
27
27
  end
28
28
 
29
29
  private
30
30
 
31
31
  def overlapping_attributes
32
32
  @overlapping_attributes ||=
33
- @collection_of_output_arguments.names.intersection(@collection_of_internal_arguments.names)
33
+ @collection_of_outputs.names.intersection(@collection_of_internals.names)
34
34
  end
35
35
  end
36
36
  end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Outputs
5
+ module Tools
6
+ class Prepare
7
+ def self.prepare(...)
8
+ new(...).prepare
9
+ end
10
+
11
+ def initialize(context, collection_of_outputs)
12
+ @context = context
13
+ @collection_of_outputs = collection_of_outputs
14
+ end
15
+
16
+ def prepare
17
+ @collection_of_outputs.each do |output|
18
+ create_instance_variable_for(output)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def create_instance_variable_for(output)
25
+ @context.instance_variable_set(:"@#{output.name}", nil)
26
+
27
+ @context.class.class_eval(context_output_template_for(output))
28
+ end
29
+
30
+ # EXAMPLE:
31
+ #
32
+ # define_method(:user=) do |value|
33
+ # Servactory::Internals::Checks::Type.check!( context: self, output:, value: )
34
+ #
35
+ # instance_variable_set(:@user, value)
36
+ # end
37
+ #
38
+ # private
39
+ #
40
+ # attr_reader :user
41
+ #
42
+ def context_output_template_for(output)
43
+ <<-RUBY
44
+ define_method(:#{output.name}=) do |value|
45
+ Servactory::Outputs::Checks::Type.check!(
46
+ context: self,
47
+ output: output,
48
+ value: value
49
+ )
50
+
51
+ instance_variable_set(:@#{output.name}, value)
52
+ end
53
+
54
+ private
55
+
56
+ attr_reader :#{output.name}
57
+ RUBY
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Outputs
5
+ class Workbench
6
+ def self.work_with(...)
7
+ new(...)
8
+ end
9
+
10
+ def initialize(collection_of_outputs)
11
+ @collection_of_outputs = collection_of_outputs
12
+ end
13
+
14
+ def assign(context:)
15
+ @context = context
16
+ end
17
+
18
+ def find_conflicts_in!(collection_of_internals:)
19
+ Tools::Conflicts.check!(context, collection_of_outputs, collection_of_internals)
20
+ end
21
+
22
+ def prepare
23
+ Tools::Prepare.prepare(context, collection_of_outputs)
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :context, :collection_of_outputs
29
+ end
30
+ end
31
+ end
@@ -8,15 +8,15 @@ module Servactory
8
8
 
9
9
  private
10
10
 
11
- def prepare_for(context:, collection_of_output_arguments:)
12
- prepare_outputs_with(context: context, collection_of_output_arguments: collection_of_output_arguments)
11
+ def prepare_for(context:, collection_of_outputs:)
12
+ prepare_outputs_with(context: context, collection_of_outputs: collection_of_outputs)
13
13
  prepare_statuses_with(context: context)
14
14
 
15
15
  self
16
16
  end
17
17
 
18
- def prepare_outputs_with(context:, collection_of_output_arguments:)
19
- collection_of_output_arguments.each do |output|
18
+ def prepare_outputs_with(context:, collection_of_outputs:)
19
+ collection_of_outputs.each do |output|
20
20
  self.class.attr_reader(:"#{output.name}")
21
21
 
22
22
  instance_variable_set(:"@#{output.name}", context.instance_variable_get(:"@#{output.name}"))
@@ -4,6 +4,8 @@ module Servactory
4
4
  module Utils
5
5
  module_function
6
6
 
7
+ # @param value [#to_s]
8
+ # @return [Boolean]
7
9
  def boolean?(value)
8
10
  value.to_s.casecmp("true").to_i.zero?
9
11
  end
@@ -3,8 +3,8 @@
3
3
  module Servactory
4
4
  module VERSION
5
5
  MAJOR = 1
6
- MINOR = 5
7
- PATCH = 2
6
+ MINOR = 6
7
+ PATCH = 1
8
8
 
9
9
  STRING = [MAJOR, MINOR, PATCH].join(".")
10
10
  end