servactory 1.5.2 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
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