typed_operation 0.3.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b3c88c55bf10a3d9d6582adfbb253c94a1fd6cf287794089775c9a8dbf1dfd86
4
- data.tar.gz: baee565ac599fb5351d1758fe720587e6793114c8ec830cbe3db6d5dc40b2d61
3
+ metadata.gz: 1d1be5d239791c002be2003d22a4d1a3bad636d10f5b3b923810627e5427f6d1
4
+ data.tar.gz: e539e29bb32268211d6831866ee5b455f11b96b1949b0ec788a8cd0ae90cb094
5
5
  SHA512:
6
- metadata.gz: 32a92d0277fee468925bd0a3c5b4b377ebb8107b3202ea13f1c23925532df4665efffaac90e76c32060f629cb9a476e654abba406e80c28da7bcf590e504c445
7
- data.tar.gz: 82d9ae76e6ba43564a3632d577ddf99ab92758c4b44cfad985a812b121c1c63efee7ceba0d92e1839c8fc6b5a0476a4914d4a33fdeca6a84bce9f0caca6c7789
6
+ metadata.gz: 0a0cccfd3499f7cd87e73ed646163f8617125e3c07dc9259972bdbc83d50634b32b129675e9d8bcf85aaef816b61f933d096aa2c6867bcde79c88b45d43cd491
7
+ data.tar.gz: 6cf1a3f0d2d7a70e57d361cdff698ddbb29505bf8177b54db9bfba83b54f64cf23983f984d990b75d2278ffbfca0c2548d2b57d8736d1acb6ac3410f58e136c6
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 :required_param, String
8
+ param :an_optional_param, Integer, convert: true, 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 :required_param, String
24
+ param :an_optional_param, Integer, convert: true, 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,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ <% if namespace_name.present? %>
6
+ module <%= namespace_name %>
7
+ class <%= name %>Test < ActiveSupport::TestCase
8
+ def setup
9
+ @operation = <%= name %>.new(required_param: "test")
10
+ end
11
+
12
+ test "should raise ParameterError if required param is nil" do
13
+ assert_raises(ParameterError) do
14
+ <%= name %>.new(required_param: nil)
15
+ end
16
+ end
17
+
18
+ test "should convert optional_param if it is not a string" do
19
+ assert_equal <%= name %>.new(required_param: "foo", optional_param: 123).converts_param, "123"
20
+ end
21
+
22
+ test "call returns after operation" do
23
+ result = @operation.call
24
+ assert_equal result, "Hello World!"
25
+ end
26
+ end
27
+ end
28
+ <% else %>
29
+ class <%= name %>Test < ActiveSupport::TestCase
30
+ def setup
31
+ @operation = <%= name %>.new(required_param: "test")
32
+ end
33
+
34
+ test "should raise ParameterError if required param is nil" do
35
+ assert_raises(ParameterError) do
36
+ <%= name %>.new(required_param: nil)
37
+ end
38
+ end
39
+
40
+ test "should convert optional_param if it is not a string" do
41
+ assert_equal <%= name %>.new(required_param: "foo", optional_param: 123).converts_param, "123"
42
+ end
43
+
44
+ test "call returns after operation" do
45
+ result = @operation.call
46
+ assert_equal result, "Hello World!"
47
+ end
48
+ end
49
+ <% 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.1"
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.1
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