amazing-activist 0.1.0 → 0.3.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: a8cba9d28e25f87ba33a43233f981a13826c716db8342fa1df5a39ed14ca59c1
4
- data.tar.gz: bcda1343f32f2df0aec0e3aaa806f602b98410e9a54d4a79214859f21830d275
3
+ metadata.gz: b5a9d6f3426a86d93d6affd8f54d19f7f071cb5142636c1b3b6fc2a12fbe87b9
4
+ data.tar.gz: d53b13cc039dee609e0d2870c560932942d3aa38009b4e7a742f7ce7ad44e9df
5
5
  SHA512:
6
- metadata.gz: c57c413901c0323f40a153d42a4b22be48281a1f6e76ceb2065cc94aed379a3d69238dfddde3537fa3ded78e573c3c9a168fcd76eb1c2547ed228b3b622f47cd
7
- data.tar.gz: 9d37d65dc06c8a8784b4bc9ea4d6c1c2d72798cfea742e292e8a4d0847451dc851024a0fef330889d27d56313d944107354dc0a7dd300aed01859bc1d67383b9
6
+ metadata.gz: '0549ced0fb0312fd5c4cca4cfc8ccaa0e359584c868497a5eea3caa7ad246958de12566d5f33525d555f6bbd9c3a77eb3536514d0e555b83a8a629048c3d58ff'
7
+ data.tar.gz: de8d63d94501dc73c61cc626e899407846af44dc8e9cb1c603e7154d57a57720adaa0897a319782a458ed9d89eff474a510777f5083206b9da902143f89060bd
data/README.adoc CHANGED
@@ -1,4 +1,13 @@
1
1
  = AmazingActivist
2
+ :ci-url: https://github.com/ixti/amazing-activist/actions/workflows/ci.yml?query=branch%3Amain
3
+ :ci-img: https://github.com/ixti/amazing-activist/actions/workflows/ci.yml/badge.svg?branch=main
4
+ :codecov-url: https://codecov.io/gh/ixti/amazing-activist/tree/main
5
+ :codecov-img: https://codecov.io/gh/ixti/amazing-activist/graph/badge.svg?token=LXaGWwv5xl
6
+
7
+ ifdef::env-github[]
8
+ {ci-url}[image:{ci-img}[CI]]
9
+ {codecov-url}[image:{codecov-img}[codecov]]
10
+ endif::[]
2
11
 
3
12
  == Installation
4
13
 
@@ -15,7 +24,7 @@ Or install it yourself as:
15
24
 
16
25
  [source,ruby]
17
26
  ----
18
- class ApplicationActivity < AmazingActivist::Activity
27
+ class ApplicationActivity < AmazingActivist::Base
19
28
  end
20
29
 
21
30
  class OnboardingActivity < ApplicationActivity
@@ -9,7 +9,7 @@ module AmazingActivist
9
9
  #
10
10
  # [source,ruby]
11
11
  # ----
12
- # class OnboardActivity < AmazingActivist::Activity
12
+ # class OnboardActivity < AmazingActivist::Base
13
13
  # def call
14
14
  # user = User.new(params)
15
15
  #
@@ -18,8 +18,16 @@ module AmazingActivist
18
18
  # failure(:invalid_params, user: user)
19
19
  # end
20
20
  # end
21
+ #
22
+ # case OnboardActivity.call(email: "user@example.com")
23
+ # in success: user
24
+ # Current.user = user
25
+ # redirect_to dashboard_url
26
+ # else
27
+ # render :new, status: :unprocessable_entity
28
+ # end
21
29
  # ----
22
- class Activity
30
+ class Base
23
31
  class << self
24
32
  # Convenience method to initialize and immediatelly call the activity.
25
33
  # @see #initialize
@@ -53,8 +61,8 @@ module AmazingActivist
53
61
  # @param code (see Outcome::Failure#initialize)
54
62
  # @param context (see Outcome::Failure#initialize)
55
63
  # @return [Outcome::Failure]
56
- def failure(code, **context)
57
- Outcome::Failure.new(code, activity: self, context: context)
64
+ def failure(code, message: nil, exception: nil, context: {})
65
+ Outcome::Failure.new(code, activity: self, message: message, exception: exception, context: context)
58
66
  end
59
67
  end
60
68
  end
@@ -0,0 +1,4 @@
1
+ en:
2
+ amazing_activist:
3
+ failures:
4
+ not_implemented: "<%{activity}> activity has no implementation"
@@ -0,0 +1,4 @@
1
+ gl:
2
+ amazing_activist:
3
+ failures:
4
+ not_implemented: "<%{activity}> actividade non ten implementación"
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../polyglot"
3
4
  require_relative "../unwrap_error"
4
5
 
5
6
  module AmazingActivist
@@ -8,19 +9,26 @@ module AmazingActivist
8
9
  # @return [Symbol]
9
10
  attr_reader :code
10
11
 
11
- # @return [AmazingActivist::Activity]
12
+ # @return [AmazingActivist::Base]
12
13
  attr_reader :activity
13
14
 
14
- # @return [Hash{Symbol => Object}]
15
+ # @return [Exception, nil]
16
+ attr_reader :exception
17
+
18
+ # @return [Hash]
15
19
  attr_reader :context
16
20
 
17
21
  # @param code [#to_sym]
18
22
  # @param activity [AmazingActivist::Activity]
19
- # @param context [Hash{Symbol => Object}]
20
- def initialize(code, activity:, context:)
21
- @code = code.to_sym
22
- @activity = activity
23
- @context = context
23
+ # @param message [#to_s, nil]
24
+ # @param exception [Exception, nil]
25
+ # @param context [Hash]
26
+ def initialize(code, activity:, message:, exception:, context:)
27
+ @code = code.to_sym
28
+ @activity = activity
29
+ @message = message&.to_s
30
+ @exception = exception
31
+ @context = context
24
32
  end
25
33
 
26
34
  # @return [true]
@@ -34,15 +42,15 @@ module AmazingActivist
34
42
  end
35
43
 
36
44
  # @api internal
37
- # @return [Array<(:failure, Symbol, AmazingActivist::Activity, Hash{Symbol => Object})>]
45
+ # @return [Array]
38
46
  def deconstruct
39
- [:failure, @code, @activity, @context]
47
+ [:failure, @code, @activity]
40
48
  end
41
49
 
42
50
  # @api internal
43
- # @return [Hash{success: Object, activity: AmazingActivist::Activity}]
51
+ # @return [Hash]
44
52
  def deconstruct_keys(_)
45
- { failure: @code, activity: @activity, context: @context }
53
+ { failure: @code, activity: @activity, message: message, exception: exception, context: context }
46
54
  end
47
55
 
48
56
  # @yieldparam self [self]
@@ -55,8 +63,11 @@ module AmazingActivist
55
63
  raise UnwrapError, self
56
64
  end
57
65
 
66
+ # Failure message.
67
+ #
68
+ # @return [String]
58
69
  def message
59
- "#{@activity.class} failed with #{@code}"
70
+ @message || Polyglot.new(@activity).message(@code, **context)
60
71
  end
61
72
  end
62
73
  end
@@ -3,11 +3,11 @@
3
3
  module AmazingActivist
4
4
  module Outcome
5
5
  class Success
6
- # @return [AmazingActivist::Activity]
6
+ # @return [AmazingActivist::Base]
7
7
  attr_reader :activity
8
8
 
9
9
  # @param value [Object]
10
- # @param activity [AmazingActivist::Activity]
10
+ # @param activity [AmazingActivist::Base]
11
11
  def initialize(value, activity:)
12
12
  @value = value
13
13
  @activity = activity
@@ -24,13 +24,13 @@ module AmazingActivist
24
24
  end
25
25
 
26
26
  # @api internal
27
- # @return [Array<(:success, Object, AmazingActivist::Activity)>]
27
+ # @return [Array]
28
28
  def deconstruct
29
29
  [:success, @value, @activity]
30
30
  end
31
31
 
32
32
  # @api internal
33
- # @return [Hash{success: Object, activity: AmazingActivist::Activity}]
33
+ # @return [Hash]
34
34
  def deconstruct_keys(_)
35
35
  { success: @value, activity: @activity }
36
36
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/blank"
4
+ require "active_support/core_ext/string/inflections"
5
+
6
+ require "i18n"
7
+
8
+ I18n.load_path += Dir[File.expand_path("#{__dir__}/locale/*.yml")]
9
+
10
+ module AmazingActivist
11
+ # @api internal
12
+ class Polyglot
13
+ ANONYMOUS_ACTIVITY_NAME = "anonymous"
14
+ private_constant :ANONYMOUS_ACTIVITY_NAME
15
+
16
+ def initialize(activity)
17
+ @activity = activity
18
+ end
19
+
20
+ # The i18n key for the message will be looked in namespaces:
21
+ #
22
+ # * `amazing_activist.activities.[activity].failures`
23
+ # * `amazing_activist.failures`
24
+ #
25
+ # Thus, if activity `Pretty::DamnGoodActivity` failed with `:bad_choise`
26
+ # code the lookup will be:
27
+ #
28
+ # * `amazing_activist.activities.pretty/damn_good.failures.bad_choice
29
+ # * `amazing_activist.failures.bad_choice
30
+ #
31
+ # If there's no translation with any of the above keys, a generic
32
+ # non-translated message will be used:
33
+ #
34
+ # <pretty/damn_good> activity failed - bad_choice
35
+ #
36
+ # @return [String] Failure message
37
+ def message(code, **context)
38
+ default = [
39
+ :"amazing_activist.failures.#{code}",
40
+ "<%{activity}> activity failed - %{code}" # rubocop:disable Style/FormatStringToken
41
+ ]
42
+
43
+ if @activity.class.name
44
+ activity = @activity.class.name.underscore.presence.delete_suffix("_activity")
45
+ i18n_key = :"amazing_activist.activities.#{activity}.failures.#{code}"
46
+ else
47
+ activity = "(anonymous)"
48
+ i18n_key = default.shift
49
+ end
50
+
51
+ I18n.t(i18n_key, **context, default: default, activity: activity, code: code)
52
+ end
53
+ end
54
+ end
@@ -13,5 +13,10 @@ module AmazingActivist
13
13
 
14
14
  super(failure.message)
15
15
  end
16
+
17
+ # @return [Exception, nil]
18
+ def cause
19
+ @failure.exception || super
20
+ end
16
21
  end
17
22
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AmazingActivist
4
- VERSION = "0.1.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "./amazing_activist/activity"
3
+ require_relative "./amazing_activist/base"
4
4
  require_relative "./amazing_activist/error"
5
5
  require_relative "./amazing_activist/outcome"
6
6
  require_relative "./amazing_activist/version"
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amazing-activist
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Zapparov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-27 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2024-02-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: i18n
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  description: Another take on Command Pattern.
14
42
  email:
15
43
  - alexey@zapparov.com
@@ -21,11 +49,14 @@ files:
21
49
  - README.adoc
22
50
  - lib/amazing-activist.rb
23
51
  - lib/amazing_activist.rb
24
- - lib/amazing_activist/activity.rb
52
+ - lib/amazing_activist/base.rb
25
53
  - lib/amazing_activist/error.rb
54
+ - lib/amazing_activist/locale/en.yml
55
+ - lib/amazing_activist/locale/gl.yml
26
56
  - lib/amazing_activist/outcome.rb
27
57
  - lib/amazing_activist/outcome/failure.rb
28
58
  - lib/amazing_activist/outcome/success.rb
59
+ - lib/amazing_activist/polyglot.rb
29
60
  - lib/amazing_activist/unwrap_error.rb
30
61
  - lib/amazing_activist/version.rb
31
62
  homepage: https://github.com/ixti/amazing-activist
@@ -33,9 +64,9 @@ licenses:
33
64
  - MIT
34
65
  metadata:
35
66
  homepage_uri: https://github.com/ixti/amazing-activist
36
- source_code_uri: https://github.com/ixti/amazing-activist/tree/v0.1.0
67
+ source_code_uri: https://github.com/ixti/amazing-activist/tree/v0.3.0
37
68
  bug_tracker_uri: https://github.com/ixti/amazing-activist/issues
38
- changelog_uri: https://github.com/ixti/amazing-activist/blob/v0.1.0/CHANGES.md
69
+ changelog_uri: https://github.com/ixti/amazing-activist/blob/v0.3.0/CHANGES.md
39
70
  rubygems_mfa_required: 'true'
40
71
  post_install_message:
41
72
  rdoc_options: []