light-service 0.18.0 → 0.19.0

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: d713cae791654b29dfc20e3cbffe16094badcc49b8221ccff0765dbd479b40c2
4
- data.tar.gz: 1e2d61c708b70466a904f8e07aa4ba4aa383bd405342efeb51014286209b2ebb
3
+ metadata.gz: d569b02dd645032b8b5bf18aaaff2a571255cbb899b1c3975fb0f3708a740d4d
4
+ data.tar.gz: 41d774361e725cf016ecb5c168773a3e2cb0155b16fa4953b693c211cc77df22
5
5
  SHA512:
6
- metadata.gz: c1d3f210ecbc0430bae9f573a945d599fcbf36a4acf26f5a49b9997c735dea8eba14f367e7c7a639d5cb8ff458feb5945ecd0078986140f763bb17b967947389
7
- data.tar.gz: d2715e9fe494e4163efd52b4e2ce32011c3e275e8bdd1ba45e8ef1c2aff8705f2d2c994e02de0b8e20896ea5067ec75fb6a7ca333ac7f9b333544fcd82d2c7ca
6
+ metadata.gz: 4b1e641b0136f71241bb047601b0003667ef1158d95635d7b70c57f301b6bb0faf313ecbc5a28b07dae7e139eb947460a2d5a78c9558c7e96ae773c6c025ef93
7
+ data.tar.gz: da0f8116260901f425c9829d1b4f97c990241ecbf693ac49696c1754313e7fe890ac7ad744a86740ff885c50aa373e4517843c29534ad9376c80c6b87e8df3b5
@@ -13,16 +13,13 @@ jobs:
13
13
  fail-fast: false
14
14
  matrix:
15
15
  os: [ubuntu, macos]
16
- ruby: [2.7.4, 3.0.2, 3.1.0]
17
- gemfile: [activesupport_5, activesupport_6]
16
+ ruby: ['3.1', '3.2', '3.3']
18
17
  continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
19
- env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
20
- BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
21
18
  steps:
22
- - uses: actions/checkout@v2
19
+ - uses: actions/checkout@v3
23
20
  - uses: ruby/setup-ruby@v1
24
21
  with:
25
22
  ruby-version: ${{ matrix.ruby }}
26
- - run: bundle install
23
+ bundler-cache: true
27
24
  - run: bundle exec rspec spec
28
25
  - run: bundle exec rubocop
data/README.md CHANGED
@@ -10,29 +10,38 @@
10
10
  LightService is a powerful and flexible service skeleton framework with an emphasis on simplicity
11
11
 
12
12
  ## Table of Contents
13
- * [Why LightService?](#why-lightservice)
14
- * [Getting Started](#getting-started)
15
- * [Requirements](#requirements)
16
- * [Installation](#installation)
17
- * [Your first action](#your-first-action)
18
- * [Your first organizer](#your-first-organizer)
19
- * [Stopping the Series of Actions](#stopping-the-series-of-actions)
20
- * [Failing the Context](#failing-the-context)
21
- * [Skipping the Rest of the Actions](#skipping-the-rest-of-the-actions)
22
- * [Benchmarking Actions with Around Advice](#benchmarking-actions-with-around-advice)
23
- * [Before and After Action Hooks](#before-and-after-action-hooks)
24
- * [Expects and Promises](#expects-and-promises)
25
- * [Default values for optional Expected keys](#default-values-for-optional-expected-keys)
26
- * [Key Aliases](#key-aliases)
27
- * [Logging](#logging)
28
- * [Error Codes](#error-codes)
29
- * [Action Rollback](#action-rollback)
30
- * [Localizing Messages](#localizing-messages)
31
- * [Orchestrating Logic in Organizers](#orchestrating-logic-in-organizers)
32
- * [ContextFactory for Faster Action Testing](#contextfactory-for-faster-action-testing)
33
- * [Rails support](#rails-support)
34
- * [Implementations in other languages](#other-implementations)
35
- * [Contributing](#contributing)
13
+ - [Table of Contents](#table-of-contents)
14
+ - [Why LightService?](#why-lightservice)
15
+ - [Getting started](#getting-started)
16
+ - [Requirements](#requirements)
17
+ - [Installation](#installation)
18
+ - [Your first action](#your-first-action)
19
+ - [Your first organizer](#your-first-organizer)
20
+ - [Stopping the Series of Actions](#stopping-the-series-of-actions)
21
+ - [Failing the Context](#failing-the-context)
22
+ - [Skipping the rest of the actions](#skipping-the-rest-of-the-actions)
23
+ - [Benchmarking Actions with Around Advice](#benchmarking-actions-with-around-advice)
24
+ - [Before and After Action Hooks](#before-and-after-action-hooks)
25
+ - [Expects and Promises](#expects-and-promises)
26
+ - [Default values for optional Expected keys](#default-values-for-optional-expected-keys)
27
+ - [Key Aliases](#key-aliases)
28
+ - [Logging](#logging)
29
+ - [Error Codes](#error-codes)
30
+ - [Action Rollback](#action-rollback)
31
+ - [Localizing Messages](#localizing-messages)
32
+ - [Built-in localization adapter](#built-in-localization-adapter)
33
+ - [I18n localization adapter](#i18n-localization-adapter)
34
+ - [Custom localization adapter](#custom-localization-adapter)
35
+ - [Orchestrating Logic in Organizers](#orchestrating-logic-in-organizers)
36
+ - [ContextFactory for Faster Action Testing](#contextfactory-for-faster-action-testing)
37
+ - [Rails support](#rails-support)
38
+ - [Organizer generation](#organizer-generation)
39
+ - [Action generation](#action-generation)
40
+ - [Advanced action generation](#advanced-action-generation)
41
+ - [Other implementations](#other-implementations)
42
+ - [Contributing](#contributing)
43
+ - [Release Notes](#release-notes)
44
+ - [License](#license)
36
45
 
37
46
  ## Why LightService?
38
47
 
@@ -823,7 +832,61 @@ end
823
832
  ```
824
833
 
825
834
  ## Localizing Messages
826
- By default LightService provides a mechanism for easily translating your error or success messages via I18n. You can also provide your own custom localization adapter if your application's logic is more complex than what is shown here.
835
+
836
+ ### Built-in localization adapter
837
+
838
+ The built-in adapter simply uses a manually created dictionary to search for translations.
839
+
840
+ ```ruby
841
+ # lib/light_service_translations.rb
842
+ LightService::LocalizationMap.instance[:en] = {
843
+ :foo_action => {
844
+ :light_service => {
845
+ :failures => {
846
+ :exceeded_api_limit => "API limit for service Foo reached. Please try again later."
847
+ },
848
+ :successes => {
849
+ :yay => "Yaaay!"
850
+ }
851
+ }
852
+ }
853
+ }
854
+ ```
855
+
856
+ ```ruby
857
+ class FooAction
858
+ extend LightService::Action
859
+
860
+ executed do |context|
861
+ unless service_call.success?
862
+ context.fail!(:exceeded_api_limit)
863
+
864
+ # The failure message used here equates to:
865
+ # LightService::LocalizationMap.instance[:en][:foo_action][:light_service][:failures][:exceeded_api_limit]
866
+ end
867
+ end
868
+ end
869
+ ```
870
+
871
+ Nested classes will work too: `App::FooAction`, for example, would be translated to `app/foo_action` hash key.
872
+
873
+ `:en` is the default locale, but you can switch it whenever you want with
874
+
875
+ ```ruby
876
+ LightService::Configuration.locale = :it
877
+ ```
878
+
879
+ If you have `I18n` loaded in your project the default adapter will automatically be updated to use it.
880
+ But would you want to opt for the built-in localization adapter you can force it with
881
+
882
+ ```ruby
883
+ LightService::Configuration.localization_adapter = LightService::LocalizationAdapter
884
+ ```
885
+
886
+ ### I18n localization adapter
887
+
888
+ If `I18n` is loaded into your project, LightService will automatically provide a mechanism for easily translating your error or success messages via `I18n`.
889
+
827
890
 
828
891
  ```ruby
829
892
  class FooAction
@@ -881,13 +944,17 @@ module PaymentGateway
881
944
  end
882
945
  ```
883
946
 
947
+ ### Custom localization adapter
948
+
949
+ You can also provide your own custom localization adapter if your application's logic is more complex than what is shown here.
950
+
884
951
  To provide your own custom adapter, use the configuration setting and subclass the default adapter LightService provides.
885
952
 
886
953
  ```ruby
887
954
  LightService::Configuration.localization_adapter = MyLocalizer.new
888
955
 
889
956
  # lib/my_localizer.rb
890
- class MyLocalizer < LightService::LocalizationAdapter
957
+ class MyLocalizer < LightService::I18n::LocalizationAdapter
891
958
 
892
959
  # I just want to change the default lookup path
893
960
  # => "light_service.failures.payment_gateway/capture_funds"
data/RELEASES.md CHANGED
@@ -1,5 +1,10 @@
1
1
  A brief list of new features and changes introduced with the specified version.
2
2
 
3
+ ### 0.19.0
4
+ * [Implement built-in localization adapter](https://github.com/adomokos/light-service/pull/238)
5
+ * [Swap ActiveSupport::Deprecation with built-in LightSupport::Deprecation](https://github.com/adomokos/light-service/pull/241)
6
+ * [Remove Active Support dependency](https://github.com/adomokos/light-service/pull/246)
7
+
3
8
  ### 0.18.0
4
9
  * [Remove Ruby 2.6, add 3.1 to build](https://github.com/adomokos/light-service/pull/233)
5
10
  * [Add reduce_when](https://github.com/adomokos/light-service/pull/232)
@@ -1,5 +1,3 @@
1
- require 'active_support/deprecation'
2
-
3
1
  module LightService
4
2
  module Action
5
3
  def self.extended(base_class)
@@ -7,9 +5,9 @@ module LightService
7
5
  end
8
6
 
9
7
  def self.included(base_class)
10
- msg = "including LightService::Action is deprecated. " \
11
- "Please use `extend LightService::Action` instead"
12
- ActiveSupport::Deprecation.warn(msg)
8
+ warning_msg = "including LightService::Action is deprecated. " \
9
+ "Please use `extend LightService::Action` instead"
10
+ LightService::Deprecation.warn(warning_msg)
13
11
  base_class.extend Macros
14
12
  end
15
13
 
@@ -2,14 +2,22 @@ module LightService
2
2
  class Configuration
3
3
  class << self
4
4
  attr_accessor :capture_errors
5
- attr_writer :logger, :localization_adapter
5
+ attr_writer :logger, :localization_adapter, :locale
6
6
 
7
7
  def logger
8
8
  @logger ||= _default_logger
9
9
  end
10
10
 
11
11
  def localization_adapter
12
- @localization_adapter ||= LocalizationAdapter.new
12
+ @localization_adapter ||= if Module.const_defined?('I18n')
13
+ LightService::I18n::LocalizationAdapter.new
14
+ else
15
+ LocalizationAdapter.new
16
+ end
17
+ end
18
+
19
+ def locale
20
+ @locale ||= :en
13
21
  end
14
22
 
15
23
  private
@@ -1,5 +1,3 @@
1
- require 'active_support/deprecation'
2
-
3
1
  module LightService
4
2
  module Outcomes
5
3
  SUCCESS = 0
@@ -59,9 +57,9 @@ module LightService
59
57
  end
60
58
 
61
59
  def outcome
62
- msg = '`Context#outcome` attribute reader is ' \
63
- 'DEPRECATED and will be removed'
64
- ActiveSupport::Deprecation.warn(msg)
60
+ warning_msg = '`Context#outcome` attribute reader is ' \
61
+ 'DEPRECATED and will be removed'
62
+ LightService::Deprecation.warn(warning_msg)
65
63
  @outcome
66
64
  end
67
65
 
@@ -103,7 +101,7 @@ module LightService
103
101
  def skip_all!(message = nil)
104
102
  warning_msg = "Using skip_all! has been deprecated, " \
105
103
  "please use `skip_remaining!` instead."
106
- ActiveSupport::Deprecation.warn(warning_msg)
104
+ LightService::Deprecation.warn(warning_msg)
107
105
 
108
106
  skip_remaining!(message)
109
107
  end
@@ -0,0 +1,17 @@
1
+ module LightService
2
+ module Deprecation
3
+ class << self
4
+ # Basic implementation of a deprecation warning
5
+ def warn(message, callstack = caller)
6
+ # Construct the warning message
7
+ warning_message = "DEPRECATION WARNING: #{message}\n"
8
+ warning_message += "Called from: #{callstack.first}\n" unless callstack.empty?
9
+
10
+ # Output the warning message to stderr or a log file
11
+ warn warning_message
12
+
13
+ # Additional logging or actions can be added here
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,46 @@
1
+ module LightService
2
+ module I18n
3
+ class LocalizationAdapter
4
+ def failure(message_or_key, action_class, i18n_options = {})
5
+ find_translated_message(message_or_key,
6
+ action_class,
7
+ i18n_options,
8
+ :type => :failure)
9
+ end
10
+
11
+ def success(message_or_key, action_class, i18n_options = {})
12
+ find_translated_message(message_or_key,
13
+ action_class,
14
+ i18n_options,
15
+ :type => :success)
16
+ end
17
+
18
+ private
19
+
20
+ def find_translated_message(message_or_key,
21
+ action_class,
22
+ i18n_options,
23
+ type)
24
+ if message_or_key.is_a?(Symbol)
25
+ i18n_options.merge!(type)
26
+ translate(message_or_key, action_class, i18n_options)
27
+ else
28
+ message_or_key
29
+ end
30
+ end
31
+
32
+ def translate(key, action_class, options = {})
33
+ type = options.delete(:type)
34
+
35
+ scope = i18n_scope_from_class(action_class, type)
36
+ options[:scope] = scope
37
+
38
+ ::I18n.t(key, **options)
39
+ end
40
+
41
+ def i18n_scope_from_class(action_class, type)
42
+ "#{action_class.name.underscore}.light_service.#{type.to_s.pluralize}"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,44 +1,31 @@
1
1
  module LightService
2
2
  class LocalizationAdapter
3
- def failure(message_or_key, action_class, i18n_options = {})
3
+ def failure(message_or_key, action_class)
4
4
  find_translated_message(message_or_key,
5
- action_class,
6
- i18n_options,
7
- :type => :failure)
5
+ action_class.to_s.underscore,
6
+ :failures)
8
7
  end
9
8
 
10
- def success(message_or_key, action_class, i18n_options = {})
9
+ def success(message_or_key, action_class)
11
10
  find_translated_message(message_or_key,
12
- action_class,
13
- i18n_options,
14
- :type => :success)
11
+ action_class.to_s.underscore,
12
+ :successes)
15
13
  end
16
14
 
17
15
  private
18
16
 
19
- def find_translated_message(message_or_key,
20
- action_class,
21
- i18n_options,
22
- type)
17
+ def find_translated_message(message_or_key, action_class, type)
23
18
  if message_or_key.is_a?(Symbol)
24
- i18n_options.merge!(type)
25
- translate(message_or_key, action_class, i18n_options)
19
+ LightService::LocalizationMap.instance.dig(
20
+ LightService::Configuration.locale,
21
+ action_class.to_sym,
22
+ :light_service,
23
+ type,
24
+ message_or_key
25
+ )
26
26
  else
27
27
  message_or_key
28
28
  end
29
29
  end
30
-
31
- def translate(key, action_class, options = {})
32
- type = options.delete(:type)
33
-
34
- scope = i18n_scope_from_class(action_class, type)
35
- options[:scope] = scope
36
-
37
- I18n.t(key, **options)
38
- end
39
-
40
- def i18n_scope_from_class(action_class, type)
41
- "#{action_class.name.underscore}.light_service.#{type.to_s.pluralize}"
42
- end
43
30
  end
44
31
  end
@@ -0,0 +1,7 @@
1
+ require 'singleton'
2
+
3
+ module LightService
4
+ class LocalizationMap < Hash
5
+ include ::Singleton
6
+ end
7
+ end
@@ -114,9 +114,9 @@ module LightService
114
114
  end
115
115
 
116
116
  def issue_deprecation_warning_for(method_name)
117
- msg = "`Orchestrator##{method_name}` is DEPRECATED and will be " \
118
- "removed, please switch to `Organizer##{method_name} instead. "
119
- ActiveSupport::Deprecation.warn(msg)
117
+ warning_msg = "`Orchestrator##{method_name}` is DEPRECATED and will be " \
118
+ "removed, please switch to `Organizer##{method_name} instead. "
119
+ LightService::Deprecation.warn(warning_msg)
120
120
  end
121
121
  end
122
122
  end
@@ -15,7 +15,7 @@ module LightService
15
15
  "its entry method (the one that calls with & reduce) " \
16
16
  "should be named `call`. " \
17
17
  "Please use #{klass}.call going forward."
18
- ActiveSupport::Deprecation.warn(warning_msg)
18
+ LightService.deprecation_warning(warning_msg)
19
19
  end
20
20
 
21
21
  def self.caller_method(first_caller)
@@ -1,5 +1,3 @@
1
- require 'active_support/deprecation'
2
-
3
1
  module LightService
4
2
  module Organizer
5
3
  def self.extended(base_class)
@@ -10,7 +8,7 @@ module LightService
10
8
  def self.included(base_class)
11
9
  warning_msg = "including LightService::Organizer is deprecated. " \
12
10
  "Please use `extend LightService::Organizer` instead"
13
- ActiveSupport::Deprecation.warn(warning_msg)
11
+ LightService::Deprecation.warn(warning_msg)
14
12
  extended(base_class)
15
13
  end
16
14
 
@@ -34,6 +34,8 @@ module LightService
34
34
  end
35
35
  # rubocop:enable Style/ArgumentsForwarding
36
36
 
37
+ ruby2_keywords :with if RUBY_VERSION >= "2.7"
38
+
37
39
  def initialize(organizer)
38
40
  @organizer = organizer
39
41
  end
@@ -1,3 +1,3 @@
1
1
  module LightService
2
- VERSION = "0.18.0".freeze
2
+ VERSION = "0.19.0".freeze
3
3
  end
data/lib/light-service.rb CHANGED
@@ -1,13 +1,15 @@
1
1
  require 'logger'
2
- require 'active_support/core_ext/string'
3
2
 
4
3
  require 'light-service/version'
5
4
 
6
5
  require 'light-service/errors'
7
6
  require 'light-service/configuration'
8
- require 'light-service/localization_adapter'
9
7
  require 'light-service/context'
10
8
  require 'light-service/context/key_verifier'
9
+ require 'light-service/deprecation_warning'
10
+ require 'light-service/i18n/localization_adapter'
11
+ require 'light-service/localization_adapter'
12
+ require 'light-service/localization_map'
11
13
  require 'light-service/organizer/scoped_reducable'
12
14
  require 'light-service/organizer/with_reducer'
13
15
  require 'light-service/organizer/with_reducer_log_decorator'
@@ -17,15 +17,12 @@ Gem::Specification.new do |gem|
17
17
  gem.version = LightService::VERSION
18
18
  gem.required_ruby_version = '>= 2.6.0'
19
19
 
20
- gem.add_runtime_dependency("activesupport", ">= 4.0.0")
21
-
22
20
  gem.add_development_dependency("generator_spec", "~> 0.9.4")
23
21
  gem.add_development_dependency("test-unit", "~> 3.0") # Needed for generator specs.
24
- gem.add_development_dependency("appraisal", "~> 2.3")
25
22
  gem.add_development_dependency("rspec", "~> 3.0")
26
23
  gem.add_development_dependency("simplecov", "~> 0.17")
27
24
  gem.add_development_dependency("codecov", "~> 0.1")
28
25
  gem.add_development_dependency("rubocop", "~> 1.26.0")
29
26
  gem.add_development_dependency("rubocop-performance", "~> 1.2.0")
30
- gem.add_development_dependency("pry", "~> 0.12.2")
27
+ gem.add_development_dependency("pry", "~> 0.14")
31
28
  end
@@ -5,7 +5,7 @@ describe "Including is discouraged" do
5
5
  it "gives warning" do
6
6
  expected_msg = "including LightService::Organizer is deprecated. " \
7
7
  "Please use `extend LightService::Organizer` instead"
8
- expect(ActiveSupport::Deprecation).to receive(:warn)
8
+ expect(LightService::Deprecation).to receive(:warn)
9
9
  .with(expected_msg)
10
10
 
11
11
  class OrganizerIncludingLS
@@ -18,7 +18,7 @@ describe "Including is discouraged" do
18
18
  it "gives warning" do
19
19
  expected_msg = "including LightService::Action is deprecated. " \
20
20
  "Please use `extend LightService::Action` instead"
21
- expect(ActiveSupport::Deprecation).to receive(:warn)
21
+ expect(LightService::Deprecation).to receive(:warn)
22
22
  .with(expected_msg)
23
23
 
24
24
  class ActionIncludingLS
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
  require "test_doubles"
3
3
 
4
- class TestsLocalizationAdapter
4
+ class TestsI18nLocalizationAdapter
5
5
  extend LightService::Organizer
6
6
 
7
7
  def self.call(pass_or_fail, message_or_key, i18n_options = {})
@@ -9,11 +9,11 @@ class TestsLocalizationAdapter
9
9
  :pass_or_fail => pass_or_fail,
10
10
  :message_or_key => message_or_key,
11
11
  :i18n_options => i18n_options
12
- ).reduce(TestsLocalizationInvocationOptionsAction)
12
+ ).reduce(TestsI18nLocalizationInvocationOptionsAction)
13
13
  end
14
14
  end
15
15
 
16
- class TestsLocalizationInvocationOptionsAction
16
+ class TestsI18nLocalizationInvocationOptionsAction
17
17
  extend LightService::Action
18
18
  expects :pass_or_fail, :message_or_key, :i18n_options
19
19
 
@@ -27,18 +27,18 @@ class TestsLocalizationInvocationOptionsAction
27
27
  end
28
28
 
29
29
  def pass_with(message_or_key, i18n_options = {})
30
- TestsLocalizationAdapter.call(true, message_or_key, i18n_options)
30
+ TestsI18nLocalizationAdapter.call(true, message_or_key, i18n_options)
31
31
  end
32
32
 
33
33
  def fail_with(message_or_key, i18n_options = {})
34
- TestsLocalizationAdapter.call(false, message_or_key, i18n_options)
34
+ TestsI18nLocalizationAdapter.call(false, message_or_key, i18n_options)
35
35
  end
36
36
 
37
- describe "Localization Adapter" do
37
+ describe "I18n Localization Adapter" do
38
38
  before do
39
39
  I18n.backend.store_translations(
40
40
  :en,
41
- :tests_localization_invocation_options_action =>
41
+ :tests_i18n_localization_invocation_options_action =>
42
42
  {
43
43
  :light_service => {
44
44
  :failures => {
@@ -4,8 +4,8 @@ require 'test_doubles'
4
4
  describe "Organizer should invoke with/reduce from a call method" do
5
5
  context "when the organizer does not have a `call` method" do
6
6
  it "gives warning" do
7
- expect(ActiveSupport::Deprecation)
8
- .to receive(:warn)
7
+ expect(LightService)
8
+ .to receive(:deprecation_warning)
9
9
  .with(/^The <OrganizerWithoutCallMethod> class is an organizer/)
10
10
 
11
11
  class OrganizerWithoutCallMethod
@@ -22,7 +22,7 @@ describe "Organizer should invoke with/reduce from a call method" do
22
22
 
23
23
  context "when the organizer has the `call` method" do
24
24
  it "does not issue a warning" do
25
- expect(ActiveSupport::Deprecation)
25
+ expect(LightService::Deprecation)
26
26
  .not_to receive(:warn)
27
27
 
28
28
  class OrganizerWithCallMethod
@@ -12,7 +12,7 @@ RSpec.describe "skip_all! has been deprecated" do
12
12
 
13
13
  expected_msg = "Using skip_all! has been deprecated, " \
14
14
  "please use `skip_remaining!` instead."
15
- expect(ActiveSupport::Deprecation).to receive(:warn)
15
+ expect(LightService::Deprecation).to receive(:warn)
16
16
  .with(expected_msg)
17
17
 
18
18
  SkipAllDeprecatedAction.execute
data/spec/context_spec.rb CHANGED
@@ -152,7 +152,7 @@ RSpec.describe LightService::Context do
152
152
  end
153
153
 
154
154
  it "warns about the outcome attribute reader being deprecated" do
155
- expect(ActiveSupport::Deprecation).to receive(:warn)
155
+ expect(LightService::Deprecation).to receive(:warn)
156
156
 
157
157
  expect(context.outcome).to eq(::LightService::Outcomes::SUCCESS)
158
158
  end
@@ -0,0 +1,83 @@
1
+ require "spec_helper"
2
+ require 'test_doubles'
3
+
4
+ describe LightService::I18n::LocalizationAdapter do
5
+ let(:action_class) { TestDoubles::AnAction }
6
+ let(:adapter) { described_class.new }
7
+
8
+ describe "#failure" do
9
+ subject { adapter.failure(message_or_key, action_class) }
10
+
11
+ context "when provided a Symbol" do
12
+ let(:message_or_key) { :not_found }
13
+
14
+ it "translates the message" do
15
+ expected_scope = "test_doubles/an_action.light_service.failures"
16
+
17
+ expect(I18n).to receive(:t)
18
+ .with(message_or_key, :scope => expected_scope)
19
+ .and_return("message")
20
+
21
+ expect(subject).to eq("message")
22
+ end
23
+
24
+ it "allows passing interpolation options to I18n layer" do
25
+ expect(I18n).to receive(:t)
26
+ .with(message_or_key, hash_including(:i18n_variable => "value"))
27
+ .and_return("message")
28
+
29
+ subject = adapter.failure(message_or_key,
30
+ action_class,
31
+ :i18n_variable => "value")
32
+
33
+ expect(subject).to eq("message")
34
+ end
35
+ end
36
+
37
+ context "when provided a String" do
38
+ let(:message_or_key) { "action failed" }
39
+
40
+ it "returns the message" do
41
+ expect(subject).to eq(message_or_key)
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "#success" do
47
+ subject { adapter.success(message_or_key, action_class) }
48
+
49
+ context "when provided a Symbol" do
50
+ let(:message_or_key) { :not_found }
51
+
52
+ it "translates the message" do
53
+ expected_scope = "test_doubles/an_action.light_service.successes"
54
+
55
+ expect(I18n).to receive(:t)
56
+ .with(message_or_key, :scope => expected_scope)
57
+ .and_return("message")
58
+
59
+ expect(subject).to eq("message")
60
+ end
61
+
62
+ it "allows passing interpolation options to I18n layer" do
63
+ expect(I18n).to receive(:t)
64
+ .with(message_or_key, hash_including(:i18n_variable => "value"))
65
+ .and_return("message")
66
+
67
+ subject = adapter.success(message_or_key,
68
+ action_class,
69
+ :i18n_variable => "value")
70
+
71
+ expect(subject).to eq("message")
72
+ end
73
+ end
74
+
75
+ context "when provided a String" do
76
+ let(:message_or_key) { "action failed" }
77
+
78
+ it "returns the message" do
79
+ expect(subject).to eq(message_or_key)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -5,6 +5,21 @@ describe LightService::LocalizationAdapter do
5
5
  let(:action_class) { TestDoubles::AnAction }
6
6
  let(:adapter) { described_class.new }
7
7
 
8
+ before do
9
+ LightService::LocalizationMap.instance[:en] = {
10
+ :'test_doubles/an_action' => {
11
+ :light_service => {
12
+ :failures => {
13
+ :not_found => "failure message"
14
+ },
15
+ :successes => {
16
+ :not_found => "success message"
17
+ }
18
+ }
19
+ }
20
+ }
21
+ end
22
+
8
23
  describe "#failure" do
9
24
  subject { adapter.failure(message_or_key, action_class) }
10
25
 
@@ -12,25 +27,7 @@ describe LightService::LocalizationAdapter do
12
27
  let(:message_or_key) { :not_found }
13
28
 
14
29
  it "translates the message" do
15
- expected_scope = "test_doubles/an_action.light_service.failures"
16
-
17
- expect(I18n).to receive(:t)
18
- .with(message_or_key, :scope => expected_scope)
19
- .and_return("message")
20
-
21
- expect(subject).to eq("message")
22
- end
23
-
24
- it "allows passing interpolation options to I18n layer" do
25
- expect(I18n).to receive(:t)
26
- .with(message_or_key, hash_including(:i18n_variable => "value"))
27
- .and_return("message")
28
-
29
- subject = adapter.failure(message_or_key,
30
- action_class,
31
- :i18n_variable => "value")
32
-
33
- expect(subject).to eq("message")
30
+ expect(subject).to eq("failure message")
34
31
  end
35
32
  end
36
33
 
@@ -50,25 +47,7 @@ describe LightService::LocalizationAdapter do
50
47
  let(:message_or_key) { :not_found }
51
48
 
52
49
  it "translates the message" do
53
- expected_scope = "test_doubles/an_action.light_service.successes"
54
-
55
- expect(I18n).to receive(:t)
56
- .with(message_or_key, :scope => expected_scope)
57
- .and_return("message")
58
-
59
- expect(subject).to eq("message")
60
- end
61
-
62
- it "allows passing interpolation options to I18n layer" do
63
- expect(I18n).to receive(:t)
64
- .with(message_or_key, hash_including(:i18n_variable => "value"))
65
- .and_return("message")
66
-
67
- subject = adapter.success(message_or_key,
68
- action_class,
69
- :i18n_variable => "value")
70
-
71
- expect(subject).to eq("message")
50
+ expect(subject).to eq("success message")
72
51
  end
73
52
  end
74
53
 
data/spec/support.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  RSpec.shared_context 'expect orchestrator warning' do
2
2
  before do
3
- expect(ActiveSupport::Deprecation)
3
+ expect(LightService::Deprecation)
4
4
  .to receive(:warn)
5
5
  .with(/^`Orchestrator#/)
6
6
  .at_least(:once)
data/spec/test_doubles.rb CHANGED
@@ -118,6 +118,15 @@ module TestDoubles
118
118
  end
119
119
  end
120
120
 
121
+ class NamedArgumentOrganiser
122
+ extend LightService::Organizer
123
+
124
+ def self.call(number:)
125
+ with(number: number) # rubocop:disable Style/HashSyntax
126
+ .reduce([AddsTwoAction])
127
+ end
128
+ end
129
+
121
130
  class NotExplicitlyReturningContextOrganizer
122
131
  extend LightService::Organizer
123
132
 
@@ -60,3 +60,18 @@ describe 'ContextFactory - used with AdditionOrganizer' do
60
60
  end
61
61
  end
62
62
  end
63
+
64
+ describe 'ContextFactory - used with NamedArgumentOrganiser' do
65
+ let(:organizer) { TestDoubles::NamedArgumentOrganiser }
66
+
67
+ # it's relevant to test this as handling of named arguments changed between ruby 2.7 and 3.0
68
+ it 'pass named arguments to the organiser' do
69
+ ctx =
70
+ LightService::Testing::ContextFactory
71
+ .make_from(organizer)
72
+ .for(TestDoubles::AddsTwoAction)
73
+ .with(number: 2) # rubocop:disable Style/HashSyntax
74
+
75
+ expect(ctx[:number]).to eq(2)
76
+ end
77
+ end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: light-service
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Attila Domokos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-21 00:00:00.000000000 Z
11
+ date: 2024-09-08 00:00:00.000000000 Z
12
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: 4.0.0
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: 4.0.0
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: generator_spec
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -52,20 +38,6 @@ dependencies:
52
38
  - - "~>"
53
39
  - !ruby/object:Gem::Version
54
40
  version: '3.0'
55
- - !ruby/object:Gem::Dependency
56
- name: appraisal
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '2.3'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '2.3'
69
41
  - !ruby/object:Gem::Dependency
70
42
  name: rspec
71
43
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +114,14 @@ dependencies:
142
114
  requirements:
143
115
  - - "~>"
144
116
  - !ruby/object:Gem::Version
145
- version: 0.12.2
117
+ version: '0.14'
146
118
  type: :development
147
119
  prerelease: false
148
120
  version_requirements: !ruby/object:Gem::Requirement
149
121
  requirements:
150
122
  - - "~>"
151
123
  - !ruby/object:Gem::Version
152
- version: 0.12.2
124
+ version: '0.14'
153
125
  description: A service skeleton with an emphasis on simplicity
154
126
  email:
155
127
  - adomokos@gmail.com
@@ -162,15 +134,12 @@ files:
162
134
  - ".rspec"
163
135
  - ".rubocop.yml"
164
136
  - ".travis.yml"
165
- - Appraisals
166
137
  - CODE_OF_CONDUCT.md
167
138
  - Gemfile
168
139
  - LICENSE
169
140
  - README.md
170
141
  - RELEASES.md
171
142
  - Rakefile
172
- - gemfiles/activesupport_5.gemfile
173
- - gemfiles/activesupport_6.gemfile
174
143
  - lib/generators/light_service/action_generator.rb
175
144
  - lib/generators/light_service/generator_utils.rb
176
145
  - lib/generators/light_service/organizer_generator.rb
@@ -183,8 +152,11 @@ files:
183
152
  - lib/light-service/configuration.rb
184
153
  - lib/light-service/context.rb
185
154
  - lib/light-service/context/key_verifier.rb
155
+ - lib/light-service/deprecation_warning.rb
186
156
  - lib/light-service/errors.rb
157
+ - lib/light-service/i18n/localization_adapter.rb
187
158
  - lib/light-service/localization_adapter.rb
159
+ - lib/light-service/localization_map.rb
188
160
  - lib/light-service/orchestrator.rb
189
161
  - lib/light-service/organizer.rb
190
162
  - lib/light-service/organizer/execute.rb
@@ -246,6 +218,7 @@ files:
246
218
  - spec/action_spec.rb
247
219
  - spec/context/inspect_spec.rb
248
220
  - spec/context_spec.rb
221
+ - spec/i18n_localization_adapter_spec.rb
249
222
  - spec/lib/generators/action_generator_advanced_spec.rb
250
223
  - spec/lib/generators/action_generator_simple_spec.rb
251
224
  - spec/lib/generators/full_generator_test_blobs.rb
@@ -290,7 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
290
263
  - !ruby/object:Gem::Version
291
264
  version: '0'
292
265
  requirements: []
293
- rubygems_version: 3.3.12
266
+ rubygems_version: 3.5.3
294
267
  signing_key:
295
268
  specification_version: 4
296
269
  summary: A service skeleton with an emphasis on simplicity
@@ -334,6 +307,7 @@ test_files:
334
307
  - spec/action_spec.rb
335
308
  - spec/context/inspect_spec.rb
336
309
  - spec/context_spec.rb
310
+ - spec/i18n_localization_adapter_spec.rb
337
311
  - spec/lib/generators/action_generator_advanced_spec.rb
338
312
  - spec/lib/generators/action_generator_simple_spec.rb
339
313
  - spec/lib/generators/full_generator_test_blobs.rb
data/Appraisals DELETED
@@ -1,11 +0,0 @@
1
- appraise "activesupport-4" do
2
- gem "activesupport", "~> 4.0"
3
- end
4
-
5
- appraise "activesupport-5" do
6
- gem "activesupport", "~> 5.0"
7
- end
8
-
9
- appraise "activesupport-6" do
10
- gem "activesupport", "~> 6.0"
11
- end
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activesupport", "~> 5.0"
6
-
7
- gemspec :path => "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activesupport", "~> 6.0"
6
-
7
- gemspec :path => "../"