typed_operation 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b3c88c55bf10a3d9d6582adfbb253c94a1fd6cf287794089775c9a8dbf1dfd86
4
- data.tar.gz: baee565ac599fb5351d1758fe720587e6793114c8ec830cbe3db6d5dc40b2d61
3
+ metadata.gz: c80a027434c29b23257b43e03eeb8acb61a3ac300a59e0c04068ffada1dd4aa6
4
+ data.tar.gz: 6b78a70b2a46710746129f8dac3a403bdc692c761c93f3ec111bf09efec8a70e
5
5
  SHA512:
6
- metadata.gz: 32a92d0277fee468925bd0a3c5b4b377ebb8107b3202ea13f1c23925532df4665efffaac90e76c32060f629cb9a476e654abba406e80c28da7bcf590e504c445
7
- data.tar.gz: 82d9ae76e6ba43564a3632d577ddf99ab92758c4b44cfad985a812b121c1c63efee7ceba0d92e1839c8fc6b5a0476a4914d4a33fdeca6a84bce9f0caca6c7789
6
+ metadata.gz: 35baa03191cfa29e1786de975d7f8d2baf62040859922544f0d79109a8f088996521e85e3dce0c66bde1f7dd5bb2b62a5332cb7841a63a1ebe4b369d48005bb6
7
+ data.tar.gz: ebf8aea46fb0d3dcd72aa846b772f228aca21be2e04695989266218e9303e9b7760770d67f53f57ca231b41b7f502ad5145bf621a0648c6706b6e741a8e6c80e
data/README.md CHANGED
@@ -4,7 +4,7 @@ An implementation of a Command pattern, which is callable, and can be partially
4
4
 
5
5
  Inputs to the operation are specified as typed attributes using the `param` method.
6
6
 
7
- Results of the operation are a type of `Dry::Monads::Result` object.
7
+ Result format of the operation is up to you, but plays nicely with `Dry::Monads`.
8
8
 
9
9
  ### Examples:
10
10
 
@@ -12,6 +12,8 @@ A base operation class:
12
12
 
13
13
  ```ruby
14
14
  class ApplicationOperation < ::TypedOperation::Base
15
+ include Dry::Monads[:result, :do]
16
+
15
17
  param :initiator, ::RegisteredUser, allow_nil: true
16
18
 
17
19
  private
@@ -93,12 +95,19 @@ Or install it yourself as:
93
95
  $ gem install typed_operation
94
96
  ```
95
97
 
96
- ## Add an `ApplicationOperation` to your project
98
+ ### Add an `ApplicationOperation` to your project
97
99
 
98
100
  ```ruby
99
101
  bin/rails g typed_operation:install
100
102
  ```
101
103
 
104
+ Use the `--dry_monads` switch to `include Dry::Monads[:result]` into your `ApplicationOperation` (don't forget to also
105
+ add `gem "dry-monads"` to your Gemfile)
106
+
107
+ ```ruby
108
+ bin/rails g typed_operation:install --dry_monads
109
+ ```
110
+
102
111
  ## Generate a new Operation
103
112
 
104
113
  ```ruby
@@ -113,6 +122,8 @@ bin/rails g typed_operation TestOperation --path=app/operations
113
122
 
114
123
  The default path is `app/operations`.
115
124
 
125
+ The generator will also create a test file.
126
+
116
127
  ## Contributing
117
128
  Contribution directions go here.
118
129
 
@@ -4,7 +4,8 @@
4
4
  module <%= namespace_name %>
5
5
  class <%= name %> < ::ApplicationOperation
6
6
  # Replace with implementation...
7
- param :param1, String, convert: true
7
+ param :my_param, String, convert: true
8
+ param :an_optional_param, Integer, allow_nil: true
8
9
 
9
10
  def prepare
10
11
  # Prepare...
@@ -12,13 +13,15 @@ module <%= namespace_name %>
12
13
 
13
14
  def call
14
15
  # Perform...
16
+ "Hello World!"
15
17
  end
16
18
  end
17
19
  end
18
20
  <% else %>
19
21
  class <%= name %> < ::ApplicationOperation
20
22
  # Replace with implementation...
21
- param :param1, String, convert: true
23
+ param :my_param, String, convert: true
24
+ param :an_optional_param, Integer, allow_nil: true
22
25
 
23
26
  def prepare
24
27
  # Prepare...
@@ -26,6 +29,7 @@ class <%= name %> < ::ApplicationOperation
26
29
 
27
30
  def call
28
31
  # Perform...
32
+ "Hello World!"
29
33
  end
30
34
  end
31
35
  <% end %>
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ <% if namespace_name.present? %>
4
+ module <%= namespace_name %>
5
+ class <%= name %>Test < ActiveSupport::TestCase
6
+ def setup
7
+ @operation = <%= name %>.new(my_param: "test")
8
+ end
9
+
10
+ test 'should raise ParameterError if my_param is nil' do
11
+ assert_raises(ParameterError) do
12
+ <%= name %>.new(my_param: nil)
13
+ end
14
+ end
15
+
16
+ test 'should convert my_param if it is not a string' do
17
+ assert_equal <%= name %>.new(my_param: 123).my_param, "123"
18
+ end
19
+
20
+ test 'call returns after operation' do
21
+ result = @operation.call
22
+ assert_equal result, "Hello World!"
23
+ end
24
+ end
25
+ end
26
+ <% else %>
27
+ class <%= name %>Test < ActiveSupport::TestCase
28
+ def setup
29
+ @operation = <%= name %>.new(my_param: "test")
30
+ end
31
+
32
+ test 'should raise ParameterError if my_param is nil' do
33
+ assert_raises(ParameterError) do
34
+ <%= name %>.new(my_param: nil)
35
+ end
36
+ end
37
+
38
+ test 'should convert my_param if it is not a string' do
39
+ assert_equal <%= name %>.new(my_param: 123).my_param, "123"
40
+ end
41
+
42
+ test 'call returns after operation' do
43
+ result = @operation.call
44
+ assert_equal result, "Hello World!"
45
+ end
46
+ end
47
+ <% end %>
@@ -9,5 +9,13 @@ Command:
9
9
  --------
10
10
  rails generate typed_operation:install
11
11
 
12
+ Options:
13
+ --------
14
+ --dry_monads: if specified the ApplicationOperation will include dry-monads Result and Do notation.
15
+
16
+ Example:
17
+ --------
18
+ rails generate typed_operation:install
19
+
12
20
  This will create the following file:
13
21
  app/operations/application_operation.rb
@@ -5,10 +5,18 @@ require "rails/generators/base"
5
5
  module TypedOperation
6
6
  module Install
7
7
  class InstallGenerator < Rails::Generators::Base
8
+ class_option :dry_monads, type: :boolean, default: false
9
+
8
10
  source_root File.expand_path("templates", __dir__)
9
11
 
10
12
  def copy_application_operation_file
11
- copy_file "application_operation.rb", "app/operations/application_operation.rb"
13
+ template "application_operation.rb", "app/operations/application_operation.rb"
14
+ end
15
+
16
+ private
17
+
18
+ def include_dry_monads?
19
+ options[:dry_monads]
12
20
  end
13
21
  end
14
22
  end
@@ -1,5 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ApplicationOperation < ::TypedOperation::Base
4
- # Common properties & methods for operations of this application...
4
+ <% if include_dry_monads? -%>
5
+ include Dry::Monads[:result, :do]
6
+
7
+ def call!
8
+ call.value!
9
+ end
10
+
11
+ <% end -%>
12
+ # Other common parameters & methods for Operations of this application...
13
+ # ...
5
14
  end
@@ -8,10 +8,14 @@ class TypedOperationGenerator < Rails::Generators::NamedBase
8
8
  class_option :path, type: :string, default: "app/operations"
9
9
 
10
10
  def generate_operation
11
- template_path = File.join(self.class.source_root, "operation.rb")
12
- dest_path = File.join(options[:path], "#{file_name}.rb")
13
-
14
- template(template_path, dest_path)
11
+ template(
12
+ File.join(self.class.source_root, "operation.rb"),
13
+ File.join(options[:path], "#{file_name}.rb")
14
+ )
15
+ template(
16
+ File.join(self.class.source_root, "operation_test.rb"),
17
+ File.join("test/", options[:path].gsub(/\Aapp\//, ""), "#{file_name}_test.rb")
18
+ )
15
19
  end
16
20
 
17
21
  private
@@ -1,12 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/monads"
4
3
  require "vident/typed"
5
4
  require "vident/typed/attributes"
6
5
 
7
6
  module TypedOperation
8
7
  class Base
9
- include Dry::Monads[:result, :do]
10
8
  include Vident::Typed::Attributes
11
9
 
12
10
  class << self
@@ -35,7 +33,11 @@ module TypedOperation
35
33
  end
36
34
 
37
35
  def initialize(**attributes)
38
- prepare_attributes(attributes)
36
+ begin
37
+ prepare_attributes(attributes)
38
+ rescue ::Dry::Struct::Error => e
39
+ raise ParameterError, e.message
40
+ end
39
41
  prepare if respond_to?(:prepare)
40
42
  end
41
43
 
@@ -43,10 +45,6 @@ module TypedOperation
43
45
  raise NotImplementedError, "You must implement #call"
44
46
  end
45
47
 
46
- def call!
47
- call.value!
48
- end
49
-
50
48
  def to_proc
51
49
  method(:call).to_proc
52
50
  end
@@ -1,3 +1,3 @@
1
1
  module TypedOperation
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -5,5 +5,5 @@ require "typed_operation/partially_applied"
5
5
  require "typed_operation/prepared"
6
6
 
7
7
  module TypedOperation
8
- # Your code goes here...
8
+ class ParameterError < StandardError; end
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typed_operation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Ierodiaconou
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-19 00:00:00.000000000 Z
11
+ date: 2023-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -58,26 +58,6 @@ dependencies:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: '3.0'
61
- - !ruby/object:Gem::Dependency
62
- name: dry-monads
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">"
66
- - !ruby/object:Gem::Version
67
- version: '1'
68
- - - "<"
69
- - !ruby/object:Gem::Version
70
- version: '2'
71
- type: :runtime
72
- prerelease: false
73
- version_requirements: !ruby/object:Gem::Requirement
74
- requirements:
75
- - - ">"
76
- - !ruby/object:Gem::Version
77
- version: '1'
78
- - - "<"
79
- - !ruby/object:Gem::Version
80
- version: '2'
81
61
  description: TypedOperation is a command pattern implementation where inputs can be
82
62
  defined with runtime type checks. Operations can be partially applied.
83
63
  email:
@@ -91,6 +71,7 @@ files:
91
71
  - Rakefile
92
72
  - lib/generators/USAGE
93
73
  - lib/generators/templates/operation.rb
74
+ - lib/generators/templates/operation_test.rb
94
75
  - lib/generators/typed_operation/install/USAGE
95
76
  - lib/generators/typed_operation/install/install_generator.rb
96
77
  - lib/generators/typed_operation/install/templates/application_operation.rb